diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3bf0e770..26a38482a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -216,9 +216,19 @@ jobs: # Start the corpus immediately beside a serial side queue. One shared # worker budget covers both processes; file and case shard axes stay # separate so every fixture still runs exactly once in each lane. + # The tests run in a transient scope capped below the runner's 16 GB, so + # the runner itself keeps memory: past 14 GB of RAM the scope swaps, as + # the whole runner did before (a sanitized shard peaks near 16 GB), and + # when RAM and swap run out the kernel kills the scope's largest process. + # OOMPolicy=continue leaves the rest of the scope running, so vitest + # reports the killed worker and the job log names the test. - name: Tests (corpus and integration suites) run: | ulimit -c 0 + if [ -d /run/systemd/system ]; then + exec sudo --preserve-env systemd-run --scope --quiet -p MemoryMax=14G -p OOMPolicy=continue \ + --uid="$(id -u)" --gid="$(id -g)" -- env PATH="$PATH" HOME="$HOME" node scripts/ci-test.mjs + fi node scripts/ci-test.mjs tests_macos: diff --git a/CHANGELOG.md b/CHANGELOG.md index 96f13fa26..612df47b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,31 @@ All notable changes to scriptc will be documented in this file. +## 0.4.4 + +### Highlights + +- **Fixes for 0.4.3:** + - Unchanged rebuilds hit the frontend cache again. An unchanged rebuild of a 23-module program takes 93 ms instead of 1.26 s, and of tsc-ts (dev) 1.6 s instead of 58.2 s. + - The native compiler builds programs with several typed-array accesses at one masked index in a loop again, including tsc-ts's release build, which failed with SC3004. + - `x!` returned from a function, used as an arrow function's result, or passed as an argument keeps null or undefined when the destination type holds it, as JavaScript does. `x!` operands of `+`, `+=` and other conversions that hold undefined or null convert as Node does. + - Effect 4 programs whose generators yield clients built by other generators run again. + - The cache for untyped property access in programs that declare classes is reverted, fixing a crash in Effect 4 observability programs. +- **Faster:** + - Number compares and typed-array indexes use the exact integer of sums like `i + 1`: a heap sift-down over an `Int32Array` runs 17.5% faster. + - glibc's per-thread heaps use huge pages: the VS Code type-check runs 3.4% faster. + - Mid-size executables (over 1 MiB of LLVM text) build in at least eight partitions: the LLVM backend phase takes 34 to 74% less time for three.js programs of 1.4 to 7.8 MB. + - JavaScript class instances are boxed at their exact class, and stores into nested string-keyed dictionaries keep class method calls direct. + - `--target-cpu` selects an x86-64 microarchitecture level. +- **Node.js parity:** + - X25519 keys and `crypto.diffieHellman`; `existsSync` and `fs.promises` accept `file:` URLs; `Buffer.from` ranges over ArrayBuffers, the deprecated `Buffer()` constructor and `Buffer` as a value. + - Dates are objects with identity; `Promise.all` over different entry types settles on Node's turns; completion callbacks run in their call's AsyncLocalStorage context. + - TypedArray methods run on typed arrays held as untyped values, and unions of typed-array classes compile. Borrowed `TypedArray.prototype.set` calls compile and throw Node's TypeError for other targets. + - Split CommonJS `require` bindings, `__`-prefixed exports, string-key destructuring of `any` values, and record key order for values JavaScript built. +- **npm packages:** zod 4 and `@hono/zod-validator` values are projected at the declaration boundary. + + + ## 0.4.3 ### Highlights @@ -26,8 +51,6 @@ All notable changes to scriptc will be documented in this file. - **npm packages:** zod 3 compiles natively and zod 4's core runs, minified packages such as marked compile, chalk 5 and hot-shots 8 build from built-in shims, and `@hono/node-server` 2.x is built in. User code types npm package declarations at a checked, identity-preserving boundary. - **Builds:** the cached build is reused after whitespace and comment edits, function bodies are emitted on forked workers, and the LLVM emitter reads its analyses from one recorded walk of each module. - - ## 0.4.2 ### Highlights diff --git a/docs/content/docs/cli.mdx b/docs/content/docs/cli.mdx index 8b0353620..9fa5e9447 100644 --- a/docs/content/docs/cli.mdx +++ b/docs/content/docs/cli.mdx @@ -135,6 +135,9 @@ With `--sparse`, the profile leaves out the functions the runs never reached. Th
--detached-exit
On Linux, when the program calls process.exit(), hand the release of its memory to a helper process so the parent sees the exit sooner. The kernel otherwise frees the whole address space before the exit is reported, which takes tens of milliseconds per gigabyte. Opt in only where the trade-offs are acceptable: for up to about 100 ms after the exit, the helper keeps the executable mapped (overwriting the binary in place fails with "text file busy"), its memory stays charged to the cgroup, and the teardown CPU time no longer appears in the parent's resource usage. Valid only for executable builds; it has no effect on other platforms.
+
--target-cpu <baseline|x86-64-v2|x86-64-v3|x86-64-v4|native>
+
On x86-64 targets, compile the program's code for an x86-64 microarchitecture level. The default, baseline, runs on any x86-64 CPU. A higher level lets LLVM use more instructions, and the executable then runs only on CPUs that support that level. native uses the highest level the build machine supports. Valid for executable, assembly, and object output on x86-64 targets. See Target CPU.
+
--profile-generate <pattern>
On Linux, build an instrumented executable for profile-guided optimization. Each run writes a raw profile to the path pattern, where %p expands to the process ID; the LLVM_PROFILE_FILE environment variable overrides the pattern at run time. A relative pattern resolves from the current working directory. Instrumented programs run slower. Valid only for executable builds with --optimization=release or speed.
@@ -228,6 +231,43 @@ $ scriptc build app.ts --optimization=speed --profile-use app.profdata Train on workloads like the ones the program will run: code the training never reached is optimized as without a profile. The profile can be committed and reused as the program changes. Functions whose control flow changed since the profile was collected lose their profile, and the rest keep theirs, so regenerate it when much of the program has changed. [Build parallelism](/docs/how-it-works#build-parallelism) describes what a profile adds to build time. +## Target CPU + +By default, x86-64 executables run on any x86-64 CPU, so the compiler uses only the baseline instruction set (SSE2). `--target-cpu` compiles the program's code for a higher x86-64 microarchitecture level. Each level includes the ones below it: + + + + + + + + + + + + + + + + + + + + + + +
LevelAdds
x86-64-v2SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT
x86-64-v3AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE
x86-64-v4AVX-512 (F, BW, CD, DQ, VL)
+ +```console +$ scriptc build app.ts --target-cpu=x86-64-v3 -o app +``` + +Loops over typed arrays and numbers gain the most, because LLVM vectorizes them with wider registers. Some loops run slower at a higher level, so measure the program on the machines it will run on. + +An executable built for a level runs only on CPUs that support that level. On an older CPU, it crashes with an illegal-instruction signal (`SIGILL`) when it reaches an instruction the CPU lacks. A named level is portable to every machine of that level. `native` selects the highest level the build machine supports, so use it only for executables that run on the machine that built them or on identical machines. + +The level applies to the program's own code. The runtime pack keeps its baseline code. Builds for different levels never share cached artifacts, and `baseline` builds are the same as builds without the option. + ## LLVM backend scriptc generates LLVM IR and compiles it to native code. Executable builds link the result with the matching precompiled runtime pack. Use --emit=llvm to inspect the generated code. diff --git a/docs/content/limitations/builtin-apis/compression.mdx b/docs/content/limitations/builtin-apis/compression.mdx index 36cec0bc4..83b0fd683 100644 --- a/docs/content/limitations/builtin-apis/compression.mdx +++ b/docs/content/limitations/builtin-apis/compression.mdx @@ -4,4 +4,5 @@ The `Deflate`, `Inflate`, `Gzip`, `Gunzip`, `DeflateRaw`, `InflateRaw`, and `Unzip` streams, from `createGzip()` and the other factories or `new zlib.Gzip()`, accept Node's options and support writes, piping, `pipeline`, async iteration, `flush`, `params`, `close`, `reset`, and `bytesWritten`. Each output chunk is its own Buffer rather than a slice of a shared chunk-size buffer. `zlib.constants` members and their module-level copies read as Node's values. - `util.inspect`, `instanceof zlib.Gzip`, and Brotli and Zstd compression are unsupported. + The Brotli one-shots `brotliCompress` and `brotliDecompress` and their `Sync` forms, and the `BrotliCompress` and `BrotliDecompress` streams, accept Node's options, including `params` and `dictionary`, and produce the same bytes as Node. + `util.inspect` and Zstd compression are unsupported. diff --git a/docs/content/limitations/builtin-apis/filesystem-url-paths.mdx b/docs/content/limitations/builtin-apis/filesystem-url-paths.mdx index d5079ed5a..9b3580647 100644 --- a/docs/content/limitations/builtin-apis/filesystem-url-paths.mdx +++ b/docs/content/limitations/builtin-apis/filesystem-url-paths.mdx @@ -1,3 +1,3 @@ -- **Filesystem URL paths:** Synchronous `fs` functions accept `file:` URL paths and convert them as `fileURLToPath` does. - `existsSync` and the `fs.promises` functions refuse URL paths; pass `fileURLToPath(url)` instead. - A URL path after a string path, or with options that are not literals, is refused, because Node checks those arguments before it converts the URL. +- **Filesystem URL paths:** `fs` and `fs.promises` functions accept `file:` URL paths and convert them as `fileURLToPath` does; `existsSync` answers `false` and the `fs.promises` functions reject for a URL that does not convert. + A URL path with options that are not literals is refused where Node checks those options before it converts the URL, except a `readFileSync` encoding. + `fs.promises` functions also refuse a string path before a URL path; pass `fileURLToPath(url)` instead. diff --git a/docs/content/limitations/builtin-apis/url.mdx b/docs/content/limitations/builtin-apis/url.mdx index 6345e2616..c9eee85b3 100644 --- a/docs/content/limitations/builtin-apis/url.mdx +++ b/docs/content/limitations/builtin-apis/url.mdx @@ -1,4 +1,4 @@ -- **URL:** Non-ASCII or percent-escaped hosts are unsupported. +- **URL:** Hosts of special URLs that hold non-ASCII text, or percent-escapes that decode to it, throw `ERR_INVALID_URL`, and `xn--` labels are kept without Punycode validation. Absolute inputs and relative inputs with runtime string or URL bases, including optional bases, compile. `URL.canParse`, `URL.parse`, `toString()`, and `toJSON()` compile; the factories use the same parser as construction, returning `false` or `null` for rejected inputs while preserving conversion errors. `href`, `protocol`, `username`, `password`, `host`, `hostname`, `port`, `pathname`, `search`, and `hash` support assignment in native code. @@ -6,4 +6,3 @@ Native URL assignments require statically known property keys; `+=` accepts primitive operands, while other assignment operators and object operands for `+=` are refused. `origin` is read-only. `searchParams` is a live view whose identity survives query and URL replacement. - Opaque paths retain their input bytes without WHATWG C0 encoding. diff --git a/docs/content/limitations/record-identity-and-property-order.mdx b/docs/content/limitations/record-identity-and-property-order.mdx index cc16f74d5..dd180cb7b 100644 --- a/docs/content/limitations/record-identity-and-property-order.mdx +++ b/docs/content/limitations/record-identity-and-property-order.mdx @@ -4,6 +4,8 @@ Empty record layouts are also snapshots because they have no property storage. `scriptc coverage` and `scriptc build` report `SC6001` where a copied value is then written or compared, whether the record was passed as an argument, stored in a typed binding, asserted with `as`, assigned to a typed binding later, or stored as an element of a typed array literal. Typed records with declared fields, indexed records, and arrays retain identity and mutations through native checked storage. +A record or class instance converted to a string-keyed dictionary type such as `Record`, directly or through a `{}`, `object` or `unknown` binding or parameter, keeps its identity when the program writes through, compares or inspects values of that dictionary type. +Every dictionary type with the same value type then uses checked dynamic storage, which is slower than a native dictionary. Class instances retain identity at their exact type or a base class, and at any interface or object type that a class instance is passed, stored, returned, or asserted as when the program could tell a copy from the instance: values of such a type are checked views of the original object, so writes, identity comparisons, Set and Map keys, `util.inspect`, and `JSON.stringify` through them reach the instance, as in Node.js. These types use checked dynamic storage, which is slower than native record fields, for all of their values, including plain objects. A type whose values are only read field by field, from fields the class does not write after construction and does not implement as accessors, stays a native record and holds a copy. diff --git a/docs/content/limitations/untyped-values.mdx b/docs/content/limitations/untyped-values.mdx index 6a881aec3..05245a396 100644 --- a/docs/content/limitations/untyped-values.mdx +++ b/docs/content/limitations/untyped-values.mdx @@ -15,3 +15,6 @@ JavaScript argument and return conversions preserve native array references; oth Supported operations on `unknown` include truthiness, `typeof` narrowing, property access, `+`, `switch`, and `throw`. Cast before using other operations. + +In JavaScript, a call whose untyped argument could select an overload with another result type returns a checked value, whichever overload the type checker picks, and so do the unannotated bindings and functions that hold or return it. +In TypeScript, an `any` argument keeps the overload the type checker picks, and a value that selects another overload at runtime throws a `TypeError` where the result is used. diff --git a/docs/src/generated/node-v24-compatibility.json b/docs/src/generated/node-v24-compatibility.json index e463b872d..130da748c 100644 --- a/docs/src/generated/node-v24-compatibility.json +++ b/docs/src/generated/node-v24-compatibility.json @@ -18268,9 +18268,9 @@ "anchor": "err_brotli_invalid_param", "nodeStability": null, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the documented scriptc module-loader subset.", + "verification": "test-backed" } }, { @@ -71509,9 +71509,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -84302,9 +84302,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "BrotliCompress and BrotliDecompress are Transform streams over the brotli version Node bundles, with Node's parameters, dictionaries, flush, reset, error codes, and option validation; like Node's, they have no params().", + "verification": "test-backed" } }, { @@ -84325,9 +84325,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "BrotliCompress and BrotliDecompress are Transform streams over the brotli version Node bundles, with Node's parameters, dictionaries, flush, reset, error codes, and option validation; like Node's, they have no params().", + "verification": "test-backed" } }, { @@ -84349,7 +84349,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84372,7 +84372,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84395,7 +84395,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84418,7 +84418,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84441,7 +84441,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84464,7 +84464,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84487,7 +84487,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84510,7 +84510,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84533,7 +84533,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84556,7 +84556,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84579,7 +84579,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84602,7 +84602,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84625,7 +84625,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -84716,9 +84716,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -84739,9 +84739,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -84969,9 +84969,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -84992,9 +84992,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -85015,9 +85015,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -85038,9 +85038,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -85499,7 +85499,7 @@ }, "static": { "status": "partial", - "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported.", + "detail": "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported.", "verification": "test-backed" } }, @@ -85521,9 +85521,9 @@ "inherited": true }, "static": { - "status": "not-implemented", - "detail": "No static compiler lowering is registered for this API yet.", - "verification": "registry-gap" + "status": "partial", + "detail": "BrotliCompress and BrotliDecompress are Transform streams over the brotli version Node bundles, with Node's parameters, dictionaries, flush, reset, error codes, and option validation; like Node's, they have no params().", + "verification": "test-backed" } }, { @@ -85567,9 +85567,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -85590,9 +85590,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -85613,9 +85613,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { @@ -85636,9 +85636,9 @@ "inherited": true }, "static": { - "status": "refused", - "detail": "Explicitly rejected by a named compiler diagnostic.", - "verification": "explicit-refusal" + "status": "partial", + "detail": "Implemented for the call shapes accepted by the compiler lowering.", + "verification": "test-backed" } }, { diff --git a/internal/compatibility/generated/node-v24-internal.json b/internal/compatibility/generated/node-v24-internal.json index 1ee5cacd6..c3a0f90b3 100644 --- a/internal/compatibility/generated/node-v24-internal.json +++ b/internal/compatibility/generated/node-v24-internal.json @@ -32763,6 +32763,7 @@ "tests/corpus/6702-ecdh-errors.js", "tests/corpus/6708-dh-errors.js", "tests/corpus/7440-tls-server-add-context.ts", + "tests/corpus/7714-zlib-brotli-compress.cjs", "tests/corpus/caught-system-error-fields.ts", "tests/corpus/error-stack-frames.ts", "tests/corpus/error-stack-limit.ts", @@ -33555,8 +33556,11 @@ "anchor": "err_brotli_invalid_param", "nodeStability": null, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:errors" + "status": "partial", + "evidence": "compiler-feature:errors.ERR_BROTLI_INVALID_PARAM", + "tests": [ + "tests/corpus/7714-zlib-brotli-compress.cjs" + ] }, "anchorSource": "exact" }, @@ -99631,6 +99635,7 @@ "evidence": "derived:descendants", "tests": [ "packages/runtime/test/url-legacy.test.ts", + "tests/corpus/1794-searchparams-url-live.ts", "tests/corpus/5220-url-parse-warnings.ts", "tests/corpus/5221-url-parse-shapes.ts", "tests/corpus/5222-url-parse-hosts.ts", @@ -100889,8 +100894,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:url" + "status": "partial", + "evidence": "surface-manifest:node-builtin.url.urlToHttpOptions", + "tests": [ + "tests/corpus/1794-searchparams-url-live.ts" + ] }, "anchorSource": "exact" }, @@ -115904,7 +115912,10 @@ "tests/corpus/5377-zlib-stream-backpressure.cjs", "tests/corpus/5378-zlib-sync-options.cjs", "tests/corpus/5379-zlib-callback-options.ts", - "tests/corpus/5415-zlib-dynamic-inputs.cjs" + "tests/corpus/5415-zlib-dynamic-inputs.cjs", + "tests/corpus/7714-zlib-brotli-compress.cjs", + "tests/corpus/7715-zlib-brotli-decompress.cjs", + "tests/corpus/7716-zlib-brotli.ts" ] }, "anchorSource": "chapter" @@ -116387,8 +116398,11 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.BrotliCompress" + "status": "partial", + "evidence": "compiler-feature:zlib.zlib.BrotliCompress", + "tests": [ + "tests/corpus/7714-zlib-brotli-compress.cjs" + ] }, "anchorSource": "exact" }, @@ -116410,8 +116424,12 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.BrotliDecompress" + "status": "partial", + "evidence": "compiler-feature:zlib.zlib.BrotliDecompress", + "tests": [ + "tests/corpus/7715-zlib-brotli-decompress.cjs", + "tests/corpus/7716-zlib-brotli.ts" + ] }, "anchorSource": "exact" }, @@ -116929,8 +116947,11 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.createBrotliCompress" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.createBrotliCompress", + "tests": [ + "tests/corpus/7714-zlib-brotli-compress.cjs" + ] }, "anchorSource": "exact" }, @@ -116952,8 +116973,12 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.createBrotliDecompress" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.createBrotliDecompress", + "tests": [ + "tests/corpus/7715-zlib-brotli-decompress.cjs", + "tests/corpus/7716-zlib-brotli.ts" + ] }, "anchorSource": "exact" }, @@ -117259,8 +117284,11 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.brotliCompress" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.brotliCompress", + "tests": [ + "tests/corpus/7714-zlib-brotli-compress.cjs" + ] }, "anchorSource": "exact" }, @@ -117282,8 +117310,11 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.brotliCompressSync" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.brotliCompressSync", + "tests": [ + "tests/corpus/7714-zlib-brotli-compress.cjs" + ] }, "anchorSource": "exact" }, @@ -117305,8 +117336,12 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.brotliDecompress" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.brotliDecompress", + "tests": [ + "tests/corpus/7715-zlib-brotli-decompress.cjs", + "tests/corpus/7716-zlib-brotli.ts" + ] }, "anchorSource": "exact" }, @@ -117328,8 +117363,12 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.brotliDecompressSync" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.brotliDecompressSync", + "tests": [ + "tests/corpus/7715-zlib-brotli-decompress.cjs", + "tests/corpus/7716-zlib-brotli.ts" + ] }, "anchorSource": "exact" }, @@ -118346,8 +118385,11 @@ "inherited": true }, "static": { - "status": "not-implemented", - "evidence": "compiler-unmatched:zlib" + "status": "partial", + "evidence": "compiler-feature:zlib.BrotliOptions", + "tests": [ + "tests/corpus/7714-zlib-brotli-compress.cjs" + ] }, "anchorSource": "exact" }, @@ -118415,8 +118457,11 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.brotliCompress" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.brotliCompress", + "tests": [ + "tests/corpus/7714-zlib-brotli-compress.cjs" + ] }, "anchorSource": "ancestor" }, @@ -118438,8 +118483,11 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.brotliCompressSync" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.brotliCompressSync", + "tests": [ + "tests/corpus/7714-zlib-brotli-compress.cjs" + ] }, "anchorSource": "ancestor" }, @@ -118461,8 +118509,12 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.brotliDecompress" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.brotliDecompress", + "tests": [ + "tests/corpus/7715-zlib-brotli-decompress.cjs", + "tests/corpus/7716-zlib-brotli.ts" + ] }, "anchorSource": "ancestor" }, @@ -118484,8 +118536,12 @@ "inherited": true }, "static": { - "status": "refused", - "evidence": "surface-manifest:unsupported:node-builtin.zlib.brotliDecompressSync" + "status": "partial", + "evidence": "surface-manifest:node-builtin.zlib.brotliDecompressSync", + "tests": [ + "tests/corpus/7715-zlib-brotli-decompress.cjs", + "tests/corpus/7716-zlib-brotli.ts" + ] }, "anchorSource": "ancestor" }, diff --git a/internal/compatibility/src/generate.mjs b/internal/compatibility/src/generate.mjs index 662c0abd6..1b598fbd3 100644 --- a/internal/compatibility/src/generate.mjs +++ b/internal/compatibility/src/generate.mjs @@ -652,7 +652,14 @@ function publicDetail(tier) { source, ) ) { - return "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Brotli and Zstd streams remain unsupported."; + return "Deflate, Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, and Unzip are Transform streams with Node's output chunking, flush, params, reset, error codes, and option validation; Zstd streams remain unsupported."; + } + if ( + /^compiler-feature:zlib\.(?:zlib\.(?:BrotliCompress|BrotliDecompress)|BrotliOptions)$/.test( + source, + ) + ) { + return "BrotliCompress and BrotliDecompress are Transform streams over the brotli version Node bundles, with Node's parameters, dictionaries, flush, reset, error codes, and option validation; like Node's, they have no params()."; } if (source === "compiler-feature:zlib.zlib.constants") { return "Each zlib.constants member and its module-level copy reads as Node's value; the constants object itself is not a runtime value."; diff --git a/internal/compatibility/static-support.json b/internal/compatibility/static-support.json index a098390f2..ab626fe21 100644 --- a/internal/compatibility/static-support.json +++ b/internal/compatibility/static-support.json @@ -190,6 +190,12 @@ "node-builtin.util": ["tests/corpus/2440-console-inspect-args.ts", "tests/corpus/2912-promisify-fs-readfile.ts"], "node-builtin.worker_threads": ["tests/corpus/957-builtins-namespace.ts", "tests/corpus/native-worker-messages.ts", "tests/corpus/native-worker-references.ts"], "node-builtin.zlib": ["tests/corpus/1404-zlib-crypto-bytes.ts", "tests/corpus/2921-zlib-callbacks.ts", "tests/corpus/3115-zlib-static-compression-levels.ts", "tests/corpus/5370-zlib-stream-roundtrip.ts", "tests/corpus/5371-zlib-stream-chunking.cjs", "tests/corpus/5373-zlib-stream-options.cjs", "tests/corpus/5378-zlib-sync-options.cjs", "tests/corpus/5379-zlib-callback-options.ts", "tests/corpus/5415-zlib-dynamic-inputs.cjs"], + "node-builtin.zlib.brotliCompressSync": ["tests/corpus/7714-zlib-brotli-compress.cjs"], + "node-builtin.zlib.brotliCompress": ["tests/corpus/7714-zlib-brotli-compress.cjs"], + "node-builtin.zlib.createBrotliCompress": ["tests/corpus/7714-zlib-brotli-compress.cjs"], + "node-builtin.zlib.brotliDecompressSync": ["tests/corpus/7715-zlib-brotli-decompress.cjs", "tests/corpus/7716-zlib-brotli.ts"], + "node-builtin.zlib.brotliDecompress": ["tests/corpus/7715-zlib-brotli-decompress.cjs", "tests/corpus/7716-zlib-brotli.ts"], + "node-builtin.zlib.createBrotliDecompress": ["tests/corpus/7715-zlib-brotli-decompress.cjs", "tests/corpus/7716-zlib-brotli.ts"], "stdlib.fetch": ["tests/harness/fetch-conformance.test.ts"], "stdlib.map": ["tests/corpus/typed-collection-iterators.ts", "tests/corpus/typed-collection-iterator-references.ts", "tests/corpus/537-map-iter-drains.ts"], "stdlib.set": ["tests/corpus/typed-collection-iterators.ts", "tests/corpus/typed-collection-iterator-references.ts", "tests/corpus/checked-collection-iterators.ts"], @@ -406,6 +412,9 @@ { "chapter": "util", "signatures": ["`util.promisify(original)`"], "status": "partial", "evidence": ["tests/corpus/1473-promisify-execfile.ts", "tests/corpus/1573-promisify-execfile-env-spread.ts", "tests/corpus/2912-promisify-fs-readfile.ts", "tests/corpus/5625-promisify-exec.ts", "tests/corpus/5626-promisify-forms.ts", "tests/fixtures/node-types/promisify-fs.ts", "tests/corpus/5628-promisify-timers.ts", "tests/fixtures/node-types/promisify-timers.ts", "tests/corpus/5629-promisify-stream.ts", "tests/corpus/5630-promisify-zlib.ts", "tests/fixtures/node-types/promisify-zlib.ts", "tests/corpus/5631-promisify-crypto.ts", "tests/fixtures/node-types/promisify-crypto.ts", "tests/corpus/5632-promisify-dns.ts", "tests/fixtures/node-types/promisify-dns.ts", "tests/corpus/6428-promisify-callback-functions.ts", "tests/fixtures/node-types/promisify-callback-functions.ts", "tests/harness/project-config.test.ts"] }, { "chapter": "typescript", "symbols": ["type"], "status": "supported", "evidence": ["tests/corpus/2702-type-import-link-static/main.ts", "tests/corpus/2703-type-import-link-static-reexport/main.ts", "tests/corpus/2704-type-import-link-static-success/main.ts", "tests/corpus/2707-type-import-link-static-default-reexport/main.ts", "tests/harness/errors.test.ts"] }, { "chapter": "zlib", "signatures": ["Class: `zlib.Deflate`", "Class: `zlib.Inflate`", "Class: `zlib.Gzip`", "Class: `zlib.Gunzip`", "Class: `zlib.DeflateRaw`", "Class: `zlib.InflateRaw`", "Class: `zlib.Unzip`", "Class: `zlib.ZlibBase`", "`zlib.close([callback])`", "`zlib.flush([kind, ]callback)`", "`zlib.params(level, strategy, callback)`", "`zlib.reset()`", "`bytesWritten` Type: {number}", "Class: `Options`"], "status": "partial", "evidence": ["tests/corpus/5370-zlib-stream-roundtrip.ts", "tests/corpus/5371-zlib-stream-chunking.cjs", "tests/corpus/5372-zlib-stream-errors.cjs", "tests/corpus/5373-zlib-stream-options.cjs", "tests/corpus/5374-zlib-stream-flush-params.ts", "tests/corpus/5375-zlib-stream-promises.ts", "tests/corpus/5377-zlib-stream-backpressure.cjs"] }, + { "chapter": "zlib", "signatures": ["Class: `zlib.BrotliCompress`", "Class: `BrotliOptions`"], "status": "partial", "evidence": ["tests/corpus/7714-zlib-brotli-compress.cjs"] }, + { "chapter": "errors", "symbols": ["ERR_BROTLI_INVALID_PARAM"], "status": "partial", "evidence": ["tests/corpus/7714-zlib-brotli-compress.cjs"] }, + { "chapter": "zlib", "signatures": ["Class: `zlib.BrotliDecompress`"], "status": "partial", "evidence": ["tests/corpus/7715-zlib-brotli-decompress.cjs", "tests/corpus/7716-zlib-brotli.ts"] }, { "chapter": "zlib", "signatures": ["`zlib.constants`"], "status": "partial", "evidence": ["tests/corpus/5376-zlib-constants.cjs", "tests/corpus/5374-zlib-stream-flush-params.ts"] }, { "chapter": "dns", "symbols": ["dns.lookup", "dns.lookupService", "dns.getServers", "dns.getDefaultResultOrder", "dns.setDefaultResultOrder"], "status": "partial", "evidence": ["tests/corpus/5648-dns-lookup-forms.ts", "tests/corpus/5649-dns-service-servers.ts", "tests/corpus/5650-dns-lookup-errors-untyped.cjs"] }, { "chapter": "dns", "symbols": ["dnsPromises.lookup", "dnsPromises.lookupService", "dnsPromises.getDefaultResultOrder"], "status": "partial", "evidence": ["tests/corpus/dns-promises-lookup.ts", "tests/corpus/dns-promises-untyped.cjs"] }, diff --git a/packages/cli-darwin-arm64/package.json b/packages/cli-darwin-arm64/package.json index eee0ec3c8..bac01cc44 100644 --- a/packages/cli-darwin-arm64/package.json +++ b/packages/cli-darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/cli-darwin-arm64", - "version": "0.4.3", + "version": "0.4.4", "description": "Native scriptc compiler for darwin-arm64", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/cli-darwin-x64/package.json b/packages/cli-darwin-x64/package.json index b527a3cd7..6c2fb3123 100644 --- a/packages/cli-darwin-x64/package.json +++ b/packages/cli-darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/cli-darwin-x64", - "version": "0.4.3", + "version": "0.4.4", "description": "Native scriptc compiler for darwin-x64", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/cli-linux-arm64-gnu/package.json b/packages/cli-linux-arm64-gnu/package.json index 512a7cd13..289d8d6bd 100644 --- a/packages/cli-linux-arm64-gnu/package.json +++ b/packages/cli-linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/cli-linux-arm64-gnu", - "version": "0.4.3", + "version": "0.4.4", "description": "Native scriptc compiler for linux-arm64-gnu", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/cli-linux-arm64-musl/package.json b/packages/cli-linux-arm64-musl/package.json index 8d0fdfb0f..3a601ca33 100644 --- a/packages/cli-linux-arm64-musl/package.json +++ b/packages/cli-linux-arm64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/cli-linux-arm64-musl", - "version": "0.4.3", + "version": "0.4.4", "description": "Native scriptc compiler for linux-arm64-musl", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/cli-linux-x64-gnu/package.json b/packages/cli-linux-x64-gnu/package.json index b71205614..8f6b1aa5e 100644 --- a/packages/cli-linux-x64-gnu/package.json +++ b/packages/cli-linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/cli-linux-x64-gnu", - "version": "0.4.3", + "version": "0.4.4", "description": "Native scriptc compiler for linux-x64-gnu", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/cli-linux-x64-musl/package.json b/packages/cli-linux-x64-musl/package.json index eaeb6f15a..ff0d1d686 100644 --- a/packages/cli-linux-x64-musl/package.json +++ b/packages/cli-linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/cli-linux-x64-musl", - "version": "0.4.3", + "version": "0.4.4", "description": "Native scriptc compiler for linux-x64-musl", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/cli-win32-x64-msvc/package.json b/packages/cli-win32-x64-msvc/package.json index 3e3b8259f..e94ba31df 100644 --- a/packages/cli-win32-x64-msvc/package.json +++ b/packages/cli-win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/cli-win32-x64-msvc", - "version": "0.4.3", + "version": "0.4.4", "description": "Native scriptc compiler for win32-x64-msvc", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/cli/package.json b/packages/cli/package.json index 264a7f5f1..26cf10f07 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "scriptc", - "version": "0.4.3", + "version": "0.4.4", "description": "Compile ordinary TypeScript and JavaScript to small, fast native executables and WebAssembly modules that run without Node.js", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/cli/src/bootstrap.ts b/packages/cli/src/bootstrap.ts index 242a7c6f7..f14866a9c 100644 --- a/packages/cli/src/bootstrap.ts +++ b/packages/cli/src/bootstrap.ts @@ -70,6 +70,8 @@ async function tryFastPath(): Promise { values["profile-generate"] !== undefined || values["profile-use"] !== undefined || values.sparse || + // The full compiler resolves `native` against the build host. + values["target-cpu"] !== undefined || (values["external-types"] ?? []).length > 0 ) return null; @@ -200,6 +202,7 @@ async function coverageFastPath( values.emit !== undefined || values.strip || values["detached-exit"] || + values["target-cpu"] !== undefined || values.lib || values.profile !== undefined || values.ffi !== undefined || diff --git a/packages/cli/test/target-cpu.test.ts b/packages/cli/test/target-cpu.test.ts new file mode 100644 index 000000000..ca5243564 --- /dev/null +++ b/packages/cli/test/target-cpu.test.ts @@ -0,0 +1,100 @@ +import { execFile } from "node:child_process"; +import { createRequire } from "node:module"; +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +import { dirname, join } from "node:path"; +import { promisify } from "node:util"; +import { expect, test } from "vitest"; +import { hostTargetCpu } from "../../compiler/src/backend/target-cpu.js"; + +const execFileAsync = promisify(execFile); +const require = createRequire(import.meta.url); +const repoRoot = join(import.meta.dirname, "../../.."); +const cliEntry = join(repoRoot, "packages/cli/src/main.ts"); +const bootstrapEntry = join(repoRoot, "packages/cli/dist/bootstrap.js"); +const tsxLoader = join(dirname(require.resolve("tsx/package.json")), "dist/loader.mjs"); +const host = hostTargetCpu(); +const runsV3 = host === "x86-64-v3" || host === "x86-64-v4"; + +const program = `const a = new Int32Array(4096); +for (let i = 0; i < a.length; i++) a[i] = (i * 2654435761) | 0; +let s = 0; +for (let r = 0; r < 64; r++) for (let i = 0; i < a.length; i++) s = (s + a[i]!) | 0; +console.log(s); +`; + +test.runIf(process.platform === "linux" && process.arch === "x64")( + "--target-cpu compiles the program for the level without mixing cache variants", + async () => { + const dir = await mkdtemp(join("/tmp", "scriptc-target-cpu-")); + const entry = join(dir, "main.ts"); + const outPath = join(dir, "program"); + const llvmPath = join(dir, "main.ll"); + const env = { ...process.env, SCRIPTC_CACHE_DIR: join(dir, "cache") }; + const build = async (args: string[], bootstrap = false): Promise => { + await execFileAsync( + process.execPath, + [ + ...(bootstrap ? [bootstrapEntry] : ["--import", tsxLoader, cliEntry]), + "build", + entry, + "-o", + outPath, + ...args, + ], + { env, maxBuffer: 4 * 1024 * 1024 }, + ); + return readFile(llvmPath, "utf8"); + }; + try { + await writeFile(entry, program); + const expected = `${(await execFileAsync(process.execPath, [entry])).stdout}`; + const baseline = await build([]); + expect(baseline).not.toContain('"target-cpu"'); + expect(await build(["--target-cpu=baseline"])).toBe(baseline); + const v3 = await build(["--target-cpu=x86-64-v3"]); + expect(v3).toMatch(/^attributes #0 = \{ sanitize_address "target-cpu"="x86-64-v3" \}$/m); + if (runsV3) expect((await execFileAsync(outPath)).stdout).toBe(expected); + // The bootstrap's cached route builds without a level. + expect(await build([], true)).toBe(baseline); + expect((await execFileAsync(outPath)).stdout).toBe(expected); + await expect(build(["--target-cpu=haswell"])).rejects.toThrow(/unknown target CPU "haswell"/); + } finally { + await rm(dir, { recursive: true, force: true }); + } + }, + 240_000, +); + +test("--target-cpu levels are refused for arm64 and WASI targets", async () => { + const dir = await mkdtemp(join("/tmp", "scriptc-target-cpu-refusal-")); + const entry = join(dir, "main.ts"); + try { + await writeFile(entry, program); + for (const target of ["aarch64-unknown-linux-gnu", "wasm32-wasi"]) { + for (const kind of ["llvm", "asm", "obj", "exe"]) { + const build = execFileAsync( + process.execPath, + [ + "--import", + tsxLoader, + cliEntry, + "build", + entry, + `--emit=${kind}`, + "-o", + join(dir, `out-${kind}`), + "--target-cpu=x86-64-v3", + ], + { + env: { ...process.env, SCRIPTC_TARGET: target, SCRIPTC_CACHE_DIR: join(dir, "cache") }, + }, + ); + await expect(build, `${target} ${kind}`).rejects.toThrow( + /--target-cpu=x86-64-v3 requires an x86-64 target/, + ); + } + } + } finally { + await rm(dir, { recursive: true, force: true }); + } +}, 240_000); diff --git a/packages/compiler/ambient/scriptc-node-fallback.d.ts b/packages/compiler/ambient/scriptc-node-fallback.d.ts index 9cd0abdd3..1924baece 100644 --- a/packages/compiler/ambient/scriptc-node-fallback.d.ts +++ b/packages/compiler/ambient/scriptc-node-fallback.d.ts @@ -1590,7 +1590,7 @@ declare module "node:fs" { export function writeFileSync(path: string | URL, data: string, encoding: "utf8" | "utf-8"): void; export function writeFileSync(path: string | URL, data: string | Uint8Array): void; export function appendFileSync(path: string | URL, data: string | Uint8Array): void; - export function existsSync(path: string): boolean; + export function existsSync(path: string | URL): boolean; export function mkdirSync(path: string | URL): void; export function mkdirSync( path: string | URL, @@ -2231,7 +2231,7 @@ declare module "fs/promises" { stat(): Promise; [Symbol.asyncDispose](): Promise; } - export function open(path: string, flags?: string, mode?: number): Promise; + export function open(path: string | URL, flags?: string, mode?: number): Promise; export function link( existingPath: string | Uint8Array | URL, newPath: string | Uint8Array | URL, @@ -2268,14 +2268,14 @@ declare module "fs/promises" { atime: number | string | Date, mtime: number | string | Date, ): Promise; - export function readFile(path: string, encoding: "utf8" | "utf-8"): Promise; + export function readFile(path: string | URL, encoding: "utf8" | "utf-8"): Promise; export function readFile( - path: string, + path: string | URL, options: BufferEncoding | { encoding: BufferEncoding }, ): Promise; - export function readFile(path: string): Promise; + export function readFile(path: string | URL): Promise; export function writeFile( - path: string, + path: string | URL, data: string, options?: { mode?: number; @@ -2284,14 +2284,18 @@ declare module "fs/promises" { [option: string]: unknown; }, ): Promise; - export function writeFile(path: string, data: string, encoding: "utf8" | "utf-8"): Promise; + export function writeFile( + path: string | URL, + data: string, + encoding: "utf8" | "utf-8", + ): Promise; export function mkdir( - path: string, + path: string | URL, options?: { recursive?: boolean; mode?: number }, ): Promise; - export function readdir(path: string): Promise; + export function readdir(path: string | URL): Promise; export function readdir( - path: string, + path: string | URL, options: { encoding?: "utf8" | "utf-8"; withFileTypes: true; @@ -2308,12 +2312,12 @@ declare module "fs/promises" { pattern: string | readonly string[], options: import("node:fs").GlobOptionsWithFileTypes, ): AsyncIterableIterator; - export function rm(path: string): Promise; + export function rm(path: string | URL): Promise; export function rm( - path: string, + path: string | URL, options: { recursive?: boolean; force?: boolean; maxRetries?: number; retryDelay?: number }, ): Promise; - export function stat(path: string): Promise; + export function stat(path: string | URL): Promise; export function statfs( path: string | Uint8Array | URL, options?: import("node:fs").StatFsOptions & { bigint?: false }, @@ -2326,21 +2330,21 @@ declare module "fs/promises" { path: string | Uint8Array | URL, options?: import("node:fs").StatFsOptions, ): Promise; - export function realpath(path: string): Promise; - export function lstat(path: string): Promise; - export function unlink(path: string): Promise; - export function chmod(path: string, mode: number): Promise; - export function chown(path: string, uid: number, gid: number): Promise; - export function lchown(path: string, uid: number, gid: number): Promise; - export function access(path: string, mode?: number): Promise; - export function truncate(path: string, len?: number): Promise; - export function appendFile(path: string, data: string | Uint8Array): Promise; - export function copyFile(src: string, dest: string): Promise; - export function mkdtemp(prefix: string): Promise; - export function rmdir(path: string): Promise; - export function rename(oldPath: string, newPath: string): Promise; + export function realpath(path: string | URL): Promise; + export function lstat(path: string | URL): Promise; + export function unlink(path: string | URL): Promise; + export function chmod(path: string | URL, mode: number): Promise; + export function chown(path: string | URL, uid: number, gid: number): Promise; + export function lchown(path: string | URL, uid: number, gid: number): Promise; + export function access(path: string | URL, mode?: number): Promise; + export function truncate(path: string | URL, len?: number): Promise; + export function appendFile(path: string | URL, data: string | Uint8Array): Promise; + export function copyFile(src: string | URL, dest: string | URL): Promise; + export function mkdtemp(prefix: string | URL): Promise; + export function rmdir(path: string | URL): Promise; + export function rename(oldPath: string | URL, newPath: string | URL): Promise; export function opendir( - path: string, + path: string | URL, options?: import("node:fs").OpenDirOptions, ): Promise; } @@ -2792,8 +2796,9 @@ declare var URLSearchParams: { * slashes, non-empty host); pathToFileURL resolves the path and percent- * encodes it into a file: URL. The legacy API: parse() answers a Url * object, format() serializes a Url-shaped object, a string, or a URL, - * resolve() resolves one URL string against another, and the domain pair - * converts a hostname to and from its Punycode form. */ + * resolve() resolves one URL string against another, the domain pair + * converts a hostname to and from its Punycode form, and urlToHttpOptions + * builds http.request options from a URL. */ declare module "url" { export type URL = globalThis.URL; export type URLSearchParams = globalThis.URLSearchParams; @@ -2861,6 +2866,19 @@ declare module "url" { export function resolve(from: string, to: string): string; export function domainToASCII(domain: string): string; export function domainToUnicode(domain: string): string; + /** urlToHttpOptions's null-prototype request options. */ + export interface UrlHttpOptions { + protocol: string; + hostname: string; + hash: string; + search: string; + pathname: string; + path: string; + href: string; + port?: number; + auth?: string; + } + export function urlToHttpOptions(url: URL): UrlHttpOptions; } declare module "node:url" { export * from "url"; @@ -4882,9 +4900,9 @@ declare module "node:readline/promises" { * inputs with Node's default options; libz links only into zlib-using * binaries. Callback forms use the executable worker pool. Options stay * declared so reached uses receive a named SC2020 refusal. The Deflate, - * Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw and Unzip streams are - * runtime Transform streams; Brotli and Zstd remain outside the lowered - * surface. */ + * Inflate, Gzip, Gunzip, DeflateRaw, InflateRaw, Unzip, BrotliCompress + * and BrotliDecompress streams are runtime Transform streams; Zstd remains + * outside the lowered surface. */ declare module "zlib" { import { Transform } from "stream"; export interface ZlibOptions { @@ -4941,50 +4959,66 @@ declare module "zlib" { ): void; export function unzipSync(data: string | Uint8Array, options?: ZlibOptions): Buffer; export function crc32(data: string | Uint8Array, value?: number): number; - export function brotliCompressSync(data: string | Uint8Array): Buffer; - export function brotliDecompressSync(data: Uint8Array): Buffer; - /* Brotli needs a codec the static runtime does not vendor: these are - * declared so their uses receive the named refusal. */ + /* Brotli over the vendored brotli 1.2.0 (scr_brotli.c): `params` keys + * are the numeric BROTLI_PARAM_* and BROTLI_DECODER_PARAM_* constants. */ + export interface BrotliOptions { + [option: string]: unknown; + } export function brotliCompress(data: string | Uint8Array, callback: ZlibCallback): void; - export function brotliDecompress(data: Uint8Array, callback: ZlibCallback): void; - export function createBrotliCompress(options?: ZlibOptions): Transform; - export function createBrotliDecompress(options?: ZlibOptions): Transform; - export class BrotliCompress extends Transform { - constructor(options?: ZlibOptions); - } - export class BrotliDecompress extends Transform { - constructor(options?: ZlibOptions); - } + export function brotliCompress( + data: string | Uint8Array, + options: BrotliOptions, + callback: ZlibCallback, + ): void; + export function brotliCompressSync(data: string | Uint8Array, options?: BrotliOptions): Buffer; + export function brotliDecompress(data: string | Uint8Array, callback: ZlibCallback): void; + export function brotliDecompress( + data: string | Uint8Array, + options: BrotliOptions, + callback: ZlibCallback, + ): void; + export function brotliDecompressSync(data: string | Uint8Array, options?: BrotliOptions): Buffer; /* The stream classes: runtime Transform streams over the zlib engine * (scr_zlib_stream.c). createGzip(options) and new Gzip(options) build - * the same stream; options are validated at runtime with Node's rules. */ + * the same stream; options are validated at runtime with Node's rules. + * Brotli streams have no params(), as in Node. */ class ZlibBase extends Transform { readonly bytesWritten: number; flush(kind?: number, callback?: () => void): void; flush(callback: () => void): void; - params(level: number, strategy: number, callback?: () => void): void; close(callback?: () => void): void; reset(): void; } - export class Deflate extends ZlibBase { + class Zlib extends ZlibBase { + params(level: number, strategy: number, callback?: () => void): void; + } + export class BrotliCompress extends ZlibBase { + constructor(options?: BrotliOptions); + } + export class BrotliDecompress extends ZlibBase { + constructor(options?: BrotliOptions); + } + export function createBrotliCompress(options?: BrotliOptions): BrotliCompress; + export function createBrotliDecompress(options?: BrotliOptions): BrotliDecompress; + export class Deflate extends Zlib { constructor(options?: ZlibOptions); } - export class Inflate extends ZlibBase { + export class Inflate extends Zlib { constructor(options?: ZlibOptions); } - export class Gzip extends ZlibBase { + export class Gzip extends Zlib { constructor(options?: ZlibOptions); } - export class Gunzip extends ZlibBase { + export class Gunzip extends Zlib { constructor(options?: ZlibOptions); } - export class DeflateRaw extends ZlibBase { + export class DeflateRaw extends Zlib { constructor(options?: ZlibOptions); } - export class InflateRaw extends ZlibBase { + export class InflateRaw extends Zlib { constructor(options?: ZlibOptions); } - export class Unzip extends ZlibBase { + export class Unzip extends Zlib { constructor(options?: ZlibOptions); } export function createDeflate(options?: ZlibOptions): Deflate; diff --git a/packages/compiler/package.json b/packages/compiler/package.json index 60f6bd0f0..570c0a1a5 100644 --- a/packages/compiler/package.json +++ b/packages/compiler/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/compiler", - "version": "0.4.3", + "version": "0.4.4", "description": "The scriptc compiler — TypeScript/JavaScript frontend, typed IR, LLVM backend", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/compiler/src/backend/executable-features.ts b/packages/compiler/src/backend/executable-features.ts index 48be5b564..a464e0d10 100644 --- a/packages/compiler/src/backend/executable-features.ts +++ b/packages/compiler/src/backend/executable-features.ts @@ -20,6 +20,7 @@ export function executableLinkFeatures(mod: IrModule): NativeLinkFeatures { ...(features.warningReplace ? { warningReplace: true } : {}), ...(features.stdioExtended ? { stdioExtended: true } : {}), zlib: features.zlib, + ...(features.brotli ? { brotli: true } : {}), assert: features.assert, inspect: features.inspect, dynInvoke: features.dynInvoke, diff --git a/packages/compiler/src/backend/llvm/bytes-loop-versions.test.ts b/packages/compiler/src/backend/llvm/bytes-loop-versions.test.ts index de71a6ef0..aef39ef75 100644 --- a/packages/compiler/src/backend/llvm/bytes-loop-versions.test.ts +++ b/packages/compiler/src/backend/llvm/bytes-loop-versions.test.ts @@ -385,7 +385,10 @@ test("while loop counters below a bound version their accesses", () => { ]); const declared = (loop: IrStmt): IrFunction => fn([{ kind: "varDecl", localId: "i", init: ref("k"), loc }, loop]); - const versionOf = (loop: IrStmt & { kind: "while" }): BytesLoopVersion | null => { + const versionOf = ( + loop: IrStmt & { kind: "while" }, + workers = false, + ): BytesLoopVersion | null => { const f = declared(loop); const ranges = analyzeIntegerRanges(f); return matchBytesLoopVersion(loop, null, { @@ -396,7 +399,7 @@ test("while loop counters below a bound version their accesses", () => { initialized: findInitializedByteLoopBindings(f).get(loop) ?? new Set(), proven: new Set(), scalarStrings: new Set(), - workers: false, + workers, owned: new Set(), }); }; @@ -413,6 +416,11 @@ test("while loop counters below a bound version their accesses", () => { // An access after the counter advances in the same pass stays checked. const advanced = whileLoop([step, set(ref("out", f64s), ref("i"), num(0))]); expect(versionOf(advanced)).toBeNull(); + // In a worker program, a while loop versions for its counter's accesses, + // and not for thread-owned receivers alone. + expect(versionOf(copy, true)!.ownedReceivers).toHaveLength(2); + const job = whileLoop([set(ref("out", f64s), ref("k"), get(ref("src", f64s), ref("k"))), step]); + expect(versionOf(job, true)).toBeNull(); const mod: IrModule = { irVersion: 17, sourceFile: loc.file, diff --git a/packages/compiler/src/backend/llvm/bytes-loop-versions.ts b/packages/compiler/src/backend/llvm/bytes-loop-versions.ts index 2013d03e4..1b51deee1 100644 --- a/packages/compiler/src/backend/llvm/bytes-loop-versions.ts +++ b/packages/compiler/src/backend/llvm/bytes-loop-versions.ts @@ -581,6 +581,11 @@ export function matchBytesLoopVersion( pairedKept.length === 0 ) return null; + // A while loop versions only for accesses at its counters. Its other + // checks (thread-owned receivers, static indices) save a test or two per + // pass, while a second copy of its body doubles the calls it makes, which + // can keep a worker's job loop from inlining the function that runs a job. + if (loop.kind === "while" && boundedKept.length === 0) return null; const bounds = new Set(); const ownedNodes = new Set(); const used = new Set(); diff --git a/packages/compiler/src/backend/llvm/classes.ts b/packages/compiler/src/backend/llvm/classes.ts index 82e34de90..699755157 100644 --- a/packages/compiler/src/backend/llvm/classes.ts +++ b/packages/compiler/src/backend/llvm/classes.ts @@ -1410,18 +1410,18 @@ export function emitClassShapes( * statics plus their construct thunks — allocate, run the constructor over * a +1 `this`, and hand the remaining +1 out. No pending check is needed: * in-tier constructors are throw-free by construction. - * `classObjs` maps className → { nameSym } registered during body emission - * (the literal interned while the table was open). */ + * `classObjs` maps className → { nameSym, baseNameSym } registered during + * body emission (the literals interned while the table was open). */ export function emitClassObjDefs( host: ClassHost, metaMap: Map, - classObjs: Map, + classObjs: Map, fnByName: Map, llType: (t: IrType) => string, threadLocal = false, ): string[] { const out: string[] = []; - for (const [className, { nameSym }] of classObjs) { + for (const [className, { nameSym, baseNameSym }] of classObjs) { const meta = metaMap.get(className); if (!meta) throw new InternalCompilerError( @@ -1447,7 +1447,7 @@ export function emitClassObjDefs( const ctorArgs = params.map((p, i) => `${llType(p.type)} %a${i}`); const classObj = `@${mangleClassObj(className)} = internal ${threadLocal ? "thread_local " : ""}global %ScrClassObj ` + - `{ ${host.sizeType} -1, ${host.sizeType} ${intervalMeta.pre}, ${host.sizeType} ${intervalMeta.post}, ptr @${mangleCtorThunk(className)}, ptr ${nameSym}, ${host.sizeType} 0, ${host.sizeType} ${meta.def.jsLength ?? (meta.def.runtime ? 1 : 0)}, ptr null, ptr null } ; class ${className}`; + `{ ${host.sizeType} -1, ${host.sizeType} ${intervalMeta.pre}, ${host.sizeType} ${intervalMeta.post}, ptr @${mangleCtorThunk(className)}, ptr ${nameSym}, ${host.sizeType} 0, ${host.sizeType} ${meta.def.jsLength ?? (meta.def.runtime ? 1 : 0)}, ptr null, ptr null, ptr ${baseNameSym ?? "null"}, ${host.sizeType} ${meta.def.ownStaticFields ? 1 : 0} } ; class ${className}`; if (meta.def.runtime) { // A runtime-provided class: %C.construct allocates through the // runtime and returns the instance. diff --git a/packages/compiler/src/backend/llvm/dyn.ts b/packages/compiler/src/backend/llvm/dyn.ts index d90239fc3..6d02daa8b 100644 --- a/packages/compiler/src/backend/llvm/dyn.ts +++ b/packages/compiler/src/backend/llvm/dyn.ts @@ -979,7 +979,10 @@ export class LlDyn { const lPlain = B.newLabel("dm.tr.plain"); B.condBr(capsule, lCapsule, lPlain); B.startBlock(lCapsule); - if (preserveRefs) { + // A class target matches only capsules of that class (tested above): + // a materialized view is a plain object, which never carries a class + // brand, so materializing one cannot change the answer. + if (preserveRefs || (t.kind === "object" && t.className !== "%Error")) { B.terminate(`ret i1 false`); } else { const materialized = B.tmp(); diff --git a/packages/compiler/src/backend/llvm/emit-module.ts b/packages/compiler/src/backend/llvm/emit-module.ts index 16a1b1601..5aa18bf9f 100644 --- a/packages/compiler/src/backend/llvm/emit-module.ts +++ b/packages/compiler/src/backend/llvm/emit-module.ts @@ -64,6 +64,7 @@ import { literalEqualityDefinition } from "./string-literal-equality.js"; import { STRING_READ_HELPERS, stringScanDecl } from "./string-reads.js"; import { emitLibraryIdentityLines } from "../library-identity-markers.js"; import { InternalCompilerError } from "../../errors.js"; +import { targetCpuAttribute } from "../target-cpu.js"; /** The function bodies emitted in `chunks` contiguous ranges, each by its * own emitter (LlEmitter.chunkEmitter), then merged in function order: the @@ -191,6 +192,20 @@ function readRange(dir: string, range: number): { result: ChunkResult; texts: st } } +/** The attribute groups of the emitted functions: #0 for every function, + * #1 for coroutine bodies and #2 for out-of-line record clones. Each carries + * the build's `--target-cpu` level. */ +function functionAttributes(emitter: LlEmitter, hasNoInlineRecordClone: boolean): string[] { + const cpu = targetCpuAttribute(emitter.targetCpu); + return [ + `attributes #0 = { sanitize_address${cpu} }`, + ...(emitter.usesCoroutines + ? [`attributes #1 = { sanitize_address presplitcoroutine${cpu} }`] + : []), + ...(hasNoInlineRecordClone ? [`attributes #2 = { noinline sanitize_address${cpu} }`] : []), + ]; +} + export function emitModuleParts(emitter: LlEmitter): string[] { // Function bodies first (the literal/unit/fn-value tables fill as they // emit), then the file assembles around them — the runtime ABI’s order. @@ -631,7 +646,7 @@ export function emitModuleParts(emitter: LlEmitter): string[] { // class-object shape { rc, pre, post, ctor, name } — field reads on // builtin errors and classval loads GEP through these. `%ScrError = type { ${emitter.sizeType}, ptr, ptr, ptr, ptr, ptr, i8, i8, i8, i8, i8, ptr, ptr }`, - `%ScrClassObj = type { ${emitter.sizeType}, ${emitter.sizeType}, ${emitter.sizeType}, ptr, ptr, ${emitter.sizeType}, ${emitter.sizeType}, ptr, ptr }`, + `%ScrClassObj = type { ${emitter.sizeType}, ${emitter.sizeType}, ${emitter.sizeType}, ptr, ptr, ${emitter.sizeType}, ${emitter.sizeType}, ptr, ptr, ptr, ${emitter.sizeType} }`, // The runtime emitter prefix { rc, vt, reg, cls } — user subclasses // embed it (classes.ts), and bare-emitter GEPs address through it. `%ScrEmitter = type { ${emitter.sizeType}, ptr, ptr, ptr }`, @@ -972,9 +987,7 @@ export function emitModuleParts(emitter: LlEmitter): string[] { // symbols specified by the library IR instead. for (const line of emitter.emitLibDefs(globals, globalReleaseLines, stamps)) out.push(line); out.push(...emitter.inlineRcTail(flushedDecls)); - out.push(`attributes #0 = { sanitize_address }`); - if (emitter.usesCoroutines) out.push(`attributes #1 = { sanitize_address presplitcoroutine }`); - if (hasNoInlineRecordClone) out.push(`attributes #2 = { noinline sanitize_address }`); + out.push(...functionAttributes(emitter, hasNoInlineRecordClone)); out.push(``); out.push(...emitter.fieldAliasMetadata()); if (emitter.debug !== null) out.push(emitter.debug.render()); @@ -1122,9 +1135,7 @@ export function emitModuleParts(emitter: LlEmitter): string[] { // sanitize_address is inert under the plain pipeline; the sanitized // lane's -fsanitize=address link activates instrumentation over the // emitted functions too (the runtime TUs get theirs from clang). - `attributes #0 = { sanitize_address }`, - ...(emitter.usesCoroutines ? [`attributes #1 = { sanitize_address presplitcoroutine }`] : []), - ...(hasNoInlineRecordClone ? [`attributes #2 = { noinline sanitize_address }`] : []), + ...functionAttributes(emitter, hasNoInlineRecordClone), ``, ); if (emitter.mod.workers) { diff --git a/packages/compiler/src/backend/llvm/emitter.test.ts b/packages/compiler/src/backend/llvm/emitter.test.ts index 23ca9d9d6..876476cc1 100644 --- a/packages/compiler/src/backend/llvm/emitter.test.ts +++ b/packages/compiler/src/backend/llvm/emitter.test.ts @@ -201,6 +201,16 @@ test("detached exit defines the runtime opt-in symbol only when requested", () = expect(detached.replace("@scr_detached_exit = constant i8 1\n", "")).toBe(plain); }); +test("a target CPU level reaches every function attribute group and nothing else", () => { + const module = moduleFor([call()]); + const plain = emitLlvmModule(module); + expect(plain).not.toContain("target-cpu"); + const v3 = emitLlvmModule(module, { targetCpu: "x86-64-v3" }); + expect(v3).toMatch(/^attributes #0 = \{ sanitize_address "target-cpu"="x86-64-v3" \}$/m); + expect(v3.replaceAll(' "target-cpu"="x86-64-v3"', "")).toBe(plain); + expect(emitLlvmModule(module, { targetCpu: "baseline" })).toBe(plain); +}); + test("inline RC inlines every fast path at speed and keeps box releases as calls in release", () => { for (const boxed of [false, true]) { const module = moduleFor(Array.from({ length: 4 }, call), { boxed }); diff --git a/packages/compiler/src/backend/llvm/emitter.ts b/packages/compiler/src/backend/llvm/emitter.ts index 8e6b88a3a..fe50e974f 100644 --- a/packages/compiler/src/backend/llvm/emitter.ts +++ b/packages/compiler/src/backend/llvm/emitter.ts @@ -1,3 +1,4 @@ +import type { TargetCpu } from "../target-cpu.js"; import { relieveHeapPressure } from "../../heap-pressure.js"; import { wasmBoundsChecks } from "./wasm-modules.js"; import { jsTruthy } from "./jsval.js"; @@ -482,6 +483,10 @@ export interface LlvmTargetOptions { * store the instance's address over 8 in 32 bits (classes.ts * compactRefLoadLines). Elsewhere they keep 8-byte pointers. */ lowRegion?: boolean; + /** The x86-64 level the program's code may require (`--target-cpu`): + * every emitted function carries it as its `target-cpu`. Unset, code + * runs on any x86-64 CPU. */ + targetCpu?: TargetCpu; } /** LlvmTargetOptions.lowRegion for an executable: Linux targets without @@ -1048,6 +1053,7 @@ export class LlEmitter { readonly emitLibraryIdentity: boolean; readonly runtimeAbiMarker: boolean; readonly detachedExit: boolean; + readonly targetCpu: TargetCpu | undefined; readonly wasmBoundsChecks: boolean; /** Interned string literals: UTF-8 text → { symbol, byte length } — * first-use order, the runtime ABI’s determinism discipline. */ @@ -1325,7 +1331,7 @@ export class LlEmitter { /** Class objects (classes as first-class values): className → the * interned .name literal ref — registered during body emission, the * statics and construct thunks assemble around the bodies. */ - readonly classObjs = new Map(); + readonly classObjs = new Map(); private readonly unionFieldReadGroups = new Map(); /** Preorder intervals of the runtime error classes under THIS module's * class-forest numbering (main() stamps scr_error_vts with them, exactly @@ -1630,6 +1636,7 @@ export class LlEmitter { this.emitLibraryIdentity = options.emitLibraryIdentity !== false; this.runtimeAbiMarker = options.runtimeAbiMarker === true; this.detachedExit = options.detachedExit === true; + this.targetCpu = options.targetCpu; this.wasmBoundsChecks = options.wasmBoundsChecks === true || wasmBoundsChecks({ @@ -3801,8 +3808,17 @@ export class LlEmitter { /** A union value's tag (i32): the box's tag word, or the NULL test of a * nullable union's pointer. */ + /** A box's tag and payload words are written only where the box is + * built (runtime constructors and untagged stack stores), so their loads + * carry their own alias tags: element and field stores cannot change + * them, and loops keep them hoisted. */ unionTag(uName: string, unionId: string): string { - return emitUnionTag(this.B, this.nullableUnions.get(unionId), uName); + return emitUnionTag( + this.B, + this.nullableUnions.get(unionId), + uName, + this.memoryAliasAttachment("union.tag"), + ); } /** Guard for helpers that build or read a union's `%ScrUnion` box @@ -3818,7 +3834,12 @@ export class LlEmitter { /** The BORROWED payload pointer of a ref arm (scr_union_peek inlined — * the runtime's is a static inline); a nullable union is its payload. */ unionPeek(uName: string, unionId: string): string { - return emitUnionPeek(this.B, this.nullableUnions.get(unionId), uName); + return emitUnionPeek( + this.B, + this.nullableUnions.get(unionId), + uName, + this.memoryAliasAttachment("union.payload"), + ); } /** Emits `switch` over a union's tag with one block per arm; each arm @@ -4047,7 +4068,12 @@ export class LlEmitter { classObjSym(className: string): string { if (!this.classObjs.has(className)) { const meta = this.classMetaOf(className); - this.classObjs.set(className, { nameSym: this.internLiteral(classJsName(meta.def)) }); + // util.inspect prints `[class C extends B]` with the base's name. + const baseName = meta.base ? classJsName(meta.base.def) : ""; + this.classObjs.set(className, { + nameSym: this.internLiteral(classJsName(meta.def)), + baseNameSym: baseName ? this.internLiteral(baseName) : null, + }); } this.journal?.entry("classObj", className, this.classObjs.get(className)); return mangleClassObj(className); @@ -4913,7 +4939,7 @@ export class LlEmitter { return; } case "classObj": - addEntry(this.classObjs, key, value as { nameSym: string }); + addEntry(this.classObjs, key, value as { nameSym: string; baseNameSym: string | null }); return; case "retainWrapper": addEntry(this.nullableUnions.retainWrappers, key, value as string); diff --git a/packages/compiler/src/backend/llvm/expr-bytes.ts b/packages/compiler/src/backend/llvm/expr-bytes.ts index 41ddf2b9d..23025d00c 100644 --- a/packages/compiler/src/backend/llvm/expr-bytes.ts +++ b/packages/compiler/src/backend/llvm/expr-bytes.ts @@ -4,7 +4,7 @@ import { emitBorrowedInput } from "./borrowed-inputs.js"; import { BYTES_ELEMENT_SIZE, F64, type IrBytesElem, type IrExpr } from "../../ir/ir.js"; import type { LlvmEmitterContext, LlValue } from "./expr-context.js"; import { F64_INF, exactIndexLines, f64Lit, sizeToDouble } from "./common.js"; -import { exactInteger, widenInteger } from "./integer-values.js"; +import { alwaysExactInteger, exactInteger } from "./integer-values.js"; import { byteNumberAccess } from "../../ir/byte-numbers.js"; import { emitByteNumber } from "./byte-numbers.js"; import { integerOrNaNIndex, integerOrNaNRange } from "./wrapping-sums.js"; @@ -86,17 +86,18 @@ export function emitBytesIndex( ): string { const B = host.B; const index = value.name; - const integer = exactInteger(host, value, expr); - if (inBounds && integer) { - const wide = widenInteger(host, integer); - if (host.sizeType === "i64") return wide; + // The exact integer, or a wide view that always equals the double (such + // as `i + 1` of a speculated counter). + const exact = alwaysExactInteger(host, value, exactInteger(host, value, expr)); + if (inBounds && exact !== null) { + if (host.sizeType === "i64") return exact; const narrow = B.tmp(); - B.line(`${narrow} = trunc i64 ${wide} to ${host.sizeType}`); + B.line(`${narrow} = trunc i64 ${exact} to ${host.sizeType}`); return narrow; } const len = emitBytesHeaderLength(host, receiver); - if (integer) { - const wideIndex = widenInteger(host, integer); + if (exact !== null) { + const wideIndex = exact; const wideLength = host.sizeType === "i64" ? len : B.tmp(); if (host.sizeType !== "i64") B.line(`${wideLength} = zext ${host.sizeType} ${len} to i64`); const inRange = B.tmp(); @@ -936,6 +937,23 @@ export function emitBytesIntrinsic( B.line(`${t} = fcmp one double ${idx.name}, ${f64Lit(-1)}`); return { name: t, type: e.type }; } + case "indexOfElem": + case "lastIndexOfElem": + return call( + "scr_bytes_index_of_elem", + "double (ptr, double, double, i1 zeroext)", + `ptr ${r.name}, double ${args[0]!.name}, double ${args[1]!.name}, i1 ${method === "lastIndexOfElem"}`, + false, + false, + ); + case "includesElem": + return call( + "scr_bytes_includes_elem", + "zeroext i1 (ptr, double, double)", + `ptr ${r.name}, double ${args[0]!.name}, double ${args[1]!.name}`, + false, + false, + ); case "fillElem": // Per-element TypedArray fill (non-u8): slice-style index // defaults, never throws; the receiver comes back +1. diff --git a/packages/compiler/src/backend/llvm/expr-primitives.ts b/packages/compiler/src/backend/llvm/expr-primitives.ts index 2c6ce35db..ccbe3edcc 100644 --- a/packages/compiler/src/backend/llvm/expr-primitives.ts +++ b/packages/compiler/src/backend/llvm/expr-primitives.ts @@ -13,6 +13,7 @@ import { emitStringInputs } from "./string-lifetimes.js"; import { emitStringParts, numberPart, stringParts } from "./string-construction.js"; import { emitBorrowedInputs } from "./borrowed-inputs.js"; import { + alwaysExactInteger, exactInteger, int32Number, integerNumber, @@ -45,6 +46,17 @@ import { type ArrayAccess, } from "./dense-array-access.js"; import { emitWrappingSum, markWrappingOperands } from "./wrapping-sums.js"; +import { emitPowerOfTwoQuotient, isPowerOfTwoCall } from "./lib-filesystem.js"; + +/** The signed integer predicates of the number compares. */ +const INTEGER_COMPARES: Record = { + "<": "slt", + "<=": "sle", + ">": "sgt", + ">=": "sge", + "===": "eq", + "!==": "ne", +}; export function emitLiteralExpr( host: LlvmEmitterContext, @@ -318,15 +330,7 @@ export function emitOperatorExpr( if (integer) return integer; } if (cmp[e.op] !== undefined) { - const integerCmp: Record = { - "<": "slt", - "<=": "sle", - ">": "sgt", - ">=": "sge", - "===": "eq", - "!==": "ne", - }; - B.line(`${t} = icmp ${integerCmp[e.op]} i64 ${left}, ${right}`); + B.line(`${t} = icmp ${INTEGER_COMPARES[e.op]} i64 ${left}, ${right}`); return { name: t, type: e.type }; } } @@ -345,6 +349,8 @@ export function emitOperatorExpr( : emitCheckedRemainder(host, l, r, li, ri); if (checked) return checked; } + if (e.op === "/" && isPowerOfTwoCall(e.right)) + return { name: emitPowerOfTwoQuotient(host, l.name, r.name), type: e.type }; if (arith[e.op] !== undefined) { B.line(`${t} = ${arith[e.op]} double ${l.name}, ${r.name}`); const uint32 = emitWrappingSum(host, e, l, r, li, ri); @@ -356,7 +362,17 @@ export function emitOperatorExpr( if (wideInteger) value.wideInteger = wideInteger; return value; } - } else B.line(`${t} = fcmp ${cmp[e.op]} double ${l.name}, ${r.name}`); + } else { + // An operand with only a wide view, such as `i + 1` of a speculated + // counter: compare the integers when both always equal the doubles. + const left = alwaysExactInteger(host, l, li), + right = left === null ? null : alwaysExactInteger(host, r, ri); + if (left !== null && right !== null) { + B.line(`${t} = icmp ${INTEGER_COMPARES[e.op]} i64 ${left}, ${right}`); + return { name: t, type: e.type }; + } + B.line(`${t} = fcmp ${cmp[e.op]} double ${l.name}, ${r.name}`); + } } else if (bit[e.op] !== undefined) { if (e.left.type.kind !== "f64" || e.right.type.kind !== "f64") { throw new LlvmUnsupportedError( diff --git a/packages/compiler/src/backend/llvm/expr-stream-bridges.ts b/packages/compiler/src/backend/llvm/expr-stream-bridges.ts index 1acc75cec..46c2d884f 100644 --- a/packages/compiler/src/backend/llvm/expr-stream-bridges.ts +++ b/packages/compiler/src/backend/llvm/expr-stream-bridges.ts @@ -993,6 +993,28 @@ export function streamTypedRefMaterializeAdapter( : `call void @scr_error_dyn_place_name(ptr ${out}, ptr ${host.cstr(nameAfter)}, ${host.sizeType} ${Buffer.byteLength(nameAfter, "utf8")})`, ); } + // A JavaScript Error subclass's property bag records, once a dynamic + // write has committed the view, where `name` and `message` were created + // (zod's error factory assigns `name` before it defines `message`); the + // slots hold their values. A `name` the class's construction sets is + // already where errorNameAfter places it among the fields. + if ( + meta.def.errorBagOrder && + meta.root.def.name === "%Error" && + meta.def.fields.some((field) => field.name === DYN_CLASS_PROPERTIES) + ) { + host.declare(`declare void @scr_error_dyn_follow_bag(ptr, ptr, ptr, i1)`); + const { index } = classFieldIndex(meta, DYN_CLASS_PROPERTIES); + const slot = B.tmp(), + bag = B.tmp(); + B.line( + `${slot} = getelementptr inbounds %${classStructSym(t.className)}, ptr %p, i64 0, i32 ${index}`, + ); + B.line(`${bag} = load ptr, ptr ${slot}`); + B.line( + `call void @scr_error_dyn_follow_bag(ptr ${out}, ptr ${bag}, ptr %p, i1 ${nameAfter === undefined ? "false" : "true"})`, + ); + } // A frozen, sealed or non-extensible instance's view says so. if (withAttributes) { host.declare(`declare void @scr_dyn_class_view_attributes(ptr, double)`); diff --git a/packages/compiler/src/backend/llvm/integer-values.ts b/packages/compiler/src/backend/llvm/integer-values.ts index ddbcdd8da..90954f4c6 100644 --- a/packages/compiler/src/backend/llvm/integer-values.ts +++ b/packages/compiler/src/backend/llvm/integer-values.ts @@ -65,6 +65,22 @@ function magnitude(range: IntegerRange): number { return Math.max(Math.abs(range.min), Math.abs(range.max)); } +/** The bounds of a sum and a product of two magnitude bounds, as doubles. + * Below 2^53 the double result is the integer; above it the result is past + * every exactness limit either way, and rounding moves it far less than the + * margin from WIDE_BOUND to the i64 range. A result of exactly 2^53 may + * stand for 2^53 + 1 (2^53 - 1 + 2 rounds to 2^53), so it moves to the next + * double up unless the sum is exactly 2^53. */ +function sumBound(a: number, b: number): number { + const sum = a + b; + return sum === EXACT_DOUBLES && EXACT_DOUBLES - a !== b ? sum + 2 : sum; +} + +function productBound(a: number, b: number): number { + const product = a * b; + return product === EXACT_DOUBLES ? product + 2 : product; +} + /** The wide view of `l op r` for `+`, `-` and `*` when the exact operands * have no proven result range (their product or sum may pass 2^53). * @@ -98,14 +114,14 @@ export function wideArithmetic( if (op === "*") { if (lv.below !== Infinity || rv.below !== Infinity) return null; below = EXACT_DOUBLES; - bound = lv.bound * rv.bound; + bound = productBound(lv.bound, rv.bound); } else if (lv.below === Infinity && rv.below === Infinity) { below = EXACT_DOUBLES; - bound = lv.bound + rv.bound; + bound = sumBound(lv.bound, rv.bound); } else if (lv.below === Infinity || rv.below === Infinity) { const [exact, wide] = lv.below === Infinity ? [lv, rv] : [rv, lv]; below = Math.min(wide.below - exact.bound, EXACT_DOUBLES); - bound = exact.bound + wide.bound; + bound = sumBound(exact.bound, wide.bound); } else return null; if (!(bound <= WIDE_BOUND) || below < INDEX_LIMIT) return null; const operand = (value: LlValue, integer: LlInteger | null): string => @@ -134,6 +150,20 @@ export function indexInteger( return wide && wide.below >= INDEX_LIMIT ? wide.name : null; } +/** An i64 equal to a value's double wherever the value can be: its exact + * integer, or a wide view whose magnitude bound is within the magnitude below + * which the view is exact. Every integer of magnitude at most 2^53 is a + * double, so a bound equal to that limit is exact too. Null otherwise. */ +export function alwaysExactInteger( + host: LlvmEmitterContext, + value: LlValue, + integer: LlInteger | null, +): string | null { + if (integer) return widenInteger(host, integer); + const wide = value.wideInteger; + return wide && wide.bound <= wide.below ? wide.name : null; +} + export function widenInteger(host: LlvmEmitterContext, value: LlInteger): string { if (value.type === "i64") return value.name; const wide = host.B.tmp(); diff --git a/packages/compiler/src/backend/llvm/layouts.ts b/packages/compiler/src/backend/llvm/layouts.ts index 8e1f0a4c1..5c426e910 100644 --- a/packages/compiler/src/backend/llvm/layouts.ts +++ b/packages/compiler/src/backend/llvm/layouts.ts @@ -17,7 +17,7 @@ export function emitLlvmLayouts( host: ClassHost, mod: IrModule, classes: Map, - classObjects: Map, + classObjects: Map, functions: Map, llType: (type: IrType) => string, nullable?: NullableRefFields, diff --git a/packages/compiler/src/backend/llvm/lib-filesystem.ts b/packages/compiler/src/backend/llvm/lib-filesystem.ts index 7d9be632d..f0b766936 100644 --- a/packages/compiler/src/backend/llvm/lib-filesystem.ts +++ b/packages/compiler/src/backend/llvm/lib-filesystem.ts @@ -1,7 +1,7 @@ /* Focused LLVM library-call emission extracted from emitter.ts. */ import { InternalCompilerError } from "../../errors.js"; import { undefinedArmTag } from "../../ir/analysis.js"; -import { DYN, F64, STATS_T, STRING } from "../../ir/ir.js"; +import { DYN, F64, STATS_T, STRING, type IrExpr } from "../../ir/ir.js"; import { mangleRecordNew } from "../mangle.js"; import { arrNewCall, traceArg, vAdapters } from "./shapes.js"; import type { LlvmEmitterContext, LibCallExpr, LlValue } from "./expr-context.js"; @@ -1027,6 +1027,57 @@ function emitPowerOfTwo(host: LlvmEmitterContext, n: string): string { return out; } +/** `Math.pow(2, n)`, the divisor emitPowerOfTwoQuotient takes. */ +export function isPowerOfTwoCall(e: IrExpr): boolean { + return ( + e.kind === "libCall" && + e.fn === "math.pow" && + e.args.length === 2 && + e.args[0]!.kind === "numLit" && + e.args[0]!.value === 2 + ); +} + +/** `left / divisor` for a divisor that is usually a power of two + * (`x / Math.pow(2, n)`). A positive power of two from 2^-1022 to 2^1022 + * has a reciprocal that is a power of two too, whose bits are + * 0x7FE0000000000000 minus the divisor's, and the product with it is the + * quotient for every `left`: both are `left` scaled by the same power of + * two, rounded once. Any other divisor divides. */ +export function emitPowerOfTwoQuotient( + host: LlvmEmitterContext, + left: string, + divisor: string, +): string { + const B = host.B; + const bits = B.tmp(), + mantissa = B.tmp(), + plain = B.tmp(), + biased = B.tmp(), + offset = B.tmp(), + normal = B.tmp(), + power = B.tmp(), + inverseBits = B.tmp(), + inverse = B.tmp(), + scaled = B.tmp(), + divided = B.tmp(), + out = B.tmp(); + B.line(`${bits} = bitcast double ${divisor} to i64`); + B.line(`${mantissa} = and i64 ${bits}, ${2n ** 52n - 1n}`); + B.line(`${plain} = icmp eq i64 ${mantissa}, 0`); + // Biased exponents 1 to 2045 with a clear sign bit. + B.line(`${biased} = lshr i64 ${bits}, 52`); + B.line(`${offset} = sub i64 ${biased}, 1`); + B.line(`${normal} = icmp ult i64 ${offset}, 2045`); + B.line(`${power} = and i1 ${plain}, ${normal}`); + B.line(`${inverseBits} = sub i64 ${0x7fe0000000000000n}, ${bits}`); + B.line(`${inverse} = bitcast i64 ${inverseBits} to double`); + B.line(`${scaled} = fmul double ${left}, ${inverse}`); + B.line(`${divided} = fdiv double ${left}, ${divisor}`); + B.line(`${out} = select i1 ${power}, double ${scaled}, double ${divided}`); + return out; +} + export function emitPrimitiveLibCall(host: LlvmEmitterContext, e: LibCallExpr): LlValue { const B = host.B; if (e.fn === "math.min" || e.fn === "math.max") { diff --git a/packages/compiler/src/backend/llvm/lib-shared.ts b/packages/compiler/src/backend/llvm/lib-shared.ts index 5383ca034..aa1244dd4 100644 --- a/packages/compiler/src/backend/llvm/lib-shared.ts +++ b/packages/compiler/src/backend/llvm/lib-shared.ts @@ -575,6 +575,7 @@ export const LIB_FN_SYMS: Record = { "zlib.deflateSync": "scr_zlib_deflate", "zlib.inflateSync": "scr_zlib_inflate", "zlib.crc32": "scr_zlib_crc32", + "zlib.brotliInstall": "scr_brotli_install", // The CA-store unit. get/set throw (an unknown type name, a // certificate-free set) and take the generic path's pending check. "tlsca.root": "scr_tls_ca_root", @@ -658,6 +659,7 @@ export const LIB_FN_SYMS: Record = { "process.stderrWriteBytes": "scr_process_stderr_write_bytes", "insp.buffer": "scr_insp_buffer", "insp.typedArray": "scr_insp_typed_array", + "insp.bytes": "scr_insp_bytes", // util.inspect (scr_inspect.c): all args borrowed; string results +1; // the begin/entry/key/moreItems/end accumulator drives the emitted // container walks. None of these throw. @@ -676,6 +678,8 @@ export const LIB_FN_SYMS: Record = { "insp.moreItems": "scr_insp_more_items", "insp.end": "scr_insp_end", "insp.nestedBegin": "scr_insp_nested_begin", + "insp.mark": "scr_insp_mark", + "insp.unwind": "scr_insp_unwind", "insp.nestedEnd": "scr_insp_nested_end", // Circular references over cycle-capable composites (Node's // seen/circular machinery — none of these throw; refWrap borrows its @@ -711,6 +715,9 @@ export const LIB_FN_SYMS: Record = { "url.hash": "scr_url_hash", "url.searchParams": "scr_url_search_params", "url.fileURLToPathUrl": "scr_url_to_path", + "url.fileURLToPathValue": "scr_url_to_path_value", + "fs.checkPath": "scr_fs_check_path", + "fs.checkReadEncoding": "scr_fs_check_read_encoding", "url.fileURLToPathChecked": "scr_url_checked_to_path", "url.fileURLToPathOptions": "scr_url_checked_to_path_options", "url.fileURLToPathBuffer": "scr_url_checked_to_path_buffer", @@ -728,6 +735,7 @@ export const LIB_FN_SYMS: Record = { "punycode.ucs2Encode": "scr_str_from_code_point", "punycode.warn": "scr_punycode_warn", "url.domainToUnicode": "scr_url_domain_to_unicode", + "url.toHttpOptions": "scr_url_to_http_options_dyn", "url.pathToFileURL": "scr_url_from_path", "url.pathToFileURLPlatform": "scr_url_from_path_platform", "url.pathToFileURLWin32": "scr_url_from_path", @@ -1059,6 +1067,7 @@ export const LIB_FN_SYMS: Record = { "dyn.generatorThis": "scr_gen_receiver", "insp.dyn": "scr_insp_dyn", "insp.dynS": "scr_insp_dyn_s", + "insp.dynHidden": "scr_insp_dyn_hidden", "fs.readFileSyncDyn": "scr_fs_read_file_sync_dyn", "fs.readFileEncoded": "scr_fs_read_file_encoded", "fs.readFdEncoded": "scr_fs_read_fd_encoded", diff --git a/packages/compiler/src/backend/llvm/reference-effects.ts b/packages/compiler/src/backend/llvm/reference-effects.ts index 6ebe1222b..43a9176d5 100644 --- a/packages/compiler/src/backend/llvm/reference-effects.ts +++ b/packages/compiler/src/backend/llvm/reference-effects.ts @@ -181,6 +181,9 @@ function expressionPreservesEdges( case "bytesIntrinsic": return ( e.method === "get" || + e.method === "indexOfElem" || + e.method === "lastIndexOfElem" || + e.method === "includesElem" || e.method === "length" || e.method === "byteLength" || e.method === "byteOffset" || diff --git a/packages/compiler/src/backend/llvm/union-repr.ts b/packages/compiler/src/backend/llvm/union-repr.ts index 959f9e51e..8c6fb4c85 100644 --- a/packages/compiler/src/backend/llvm/union-repr.ts +++ b/packages/compiler/src/backend/llvm/union-repr.ts @@ -8,8 +8,14 @@ import type { BlockBuilder } from "./blocks.js"; import { NULLABLE_NULL, shapeTagFn, type PointerUnion } from "./nullable-unions.js"; -/** The i32 tag of a union value. */ -export function emitUnionTag(B: BlockBuilder, nullable: PointerUnion | null, u: string): string { +/** The i32 tag of a union value. `alias` is the tag word's alias + * attachment (", !tbaa !N"), when the caller has one. */ +export function emitUnionTag( + B: BlockBuilder, + nullable: PointerUnion | null, + u: string, + alias = "", +): string { const t = B.tmp(); if (nullable?.repr === "shapes") { B.line(`${t} = call i32 ${shapeTagFn(nullable.unionId)}(ptr ${u})`); @@ -31,7 +37,7 @@ export function emitUnionTag(B: BlockBuilder, nullable: PointerUnion | null, u: } const p = B.tmp(); B.line(`${p} = getelementptr inbounds %ScrUnion, ptr ${u}, i64 0, i32 1`); - B.line(`${t} = load i32, ptr ${p}`); + B.line(`${t} = load i32, ptr ${p}${alias}`); return t; } @@ -81,12 +87,17 @@ export function emitNullableIsTag( } /** The BORROWED payload pointer of a reference arm. */ -export function emitUnionPeek(B: BlockBuilder, nullable: PointerUnion | null, u: string): string { +export function emitUnionPeek( + B: BlockBuilder, + nullable: PointerUnion | null, + u: string, + alias = "", +): string { if (nullable) return u; const p = B.tmp(); const t = B.tmp(); B.line(`${p} = getelementptr inbounds %ScrUnion, ptr ${u}, i64 0, i32 5`); - B.line(`${t} = load ptr, ptr ${p}`); + B.line(`${t} = load ptr, ptr ${p}${alias}`); return t; } diff --git a/packages/compiler/src/backend/native-link-info-core.ts b/packages/compiler/src/backend/native-link-info-core.ts index 1235a3f3e..cb10d856d 100644 --- a/packages/compiler/src/backend/native-link-info-core.ts +++ b/packages/compiler/src/backend/native-link-info-core.ts @@ -35,6 +35,8 @@ export interface NativeLinkFeatures { * or stdio 'resize' events: links the SCR_STDIO_EXTENDED events unit. */ stdioExtended?: boolean; zlib: boolean; + /** node:zlib's Brotli forms: scr_brotli.c and the vendored brotli archive. */ + brotli?: boolean; assert: boolean; inspect: boolean; dynInvoke: boolean; diff --git a/packages/compiler/src/backend/native/contracts.ts b/packages/compiler/src/backend/native/contracts.ts index ef84f4d10..a9ddaee51 100644 --- a/packages/compiler/src/backend/native/contracts.ts +++ b/packages/compiler/src/backend/native/contracts.ts @@ -85,6 +85,9 @@ export interface CcOptions { * compares round-trips and fixed-blob inflation, never raw deflate * output. */ zlib?: boolean; + /** The program uses node:zlib's Brotli forms (with zlib): compiles + * scr_brotli.c and links the vendored brotli archive. */ + brotli?: boolean; /** The program uses node:assert (index.ts detects assert.* libCalls on * the IR): compiles scr_assert.c — the zlib gating precedent, so * assert-free binaries keep their exact size class. scr_regex.c calls diff --git a/packages/compiler/src/backend/native/executable.ts b/packages/compiler/src/backend/native/executable.ts index 59957f664..b87699c95 100644 --- a/packages/compiler/src/backend/native/executable.ts +++ b/packages/compiler/src/backend/native/executable.ts @@ -82,15 +82,18 @@ import { currentVendorCacheBuildIdentity, vendorBuildCacheRoot, tlsArchivePath, + brotliArchivePath, lreObjectPaths, zlibObjectPaths, stageVendorInputs, ensureTlsArchive, + ensureBrotliArchive, ensureLreObjects, ensureZlibObjects, vendorEngineDir, vendorZlibDir, vendorTlsDir, + vendorBrotliDir, } from "./vendor.js"; import { execFileAsync, subprocessFailureDetail, CcCompileError } from "./process.js"; import { implicitLinkerFingerprint } from "./linker-fingerprint.js"; @@ -119,6 +122,7 @@ interface RuntimeUnitContext { lreObjects: readonly string[]; zlibObjects: readonly string[]; tlsArchive: string | null; + brotliArchive: string | null; } /** An optional runtime input: runtime sources compiled when `when` holds, @@ -222,6 +226,18 @@ const RUNTIME_UNITS: readonly RuntimeUnit[] = [ : [] : [], ), + // Brotli (scr_brotli.c) plugs into the zlib engine and links the + // vendored brotli archive. + unitArgs((u) => + u.brotliArchive + ? [ + "-I", + join(vendorBrotliDir(), "include"), + u.rt(join(u.rtDir, "scr_brotli.c")), + u.brotliArchive, + ] + : [], + ), unit((u) => u.opts.events, "scr_events.c", "scr_readline.c"), // readline's terminal mode: rl.terminal sets the regex unit it // measures with. @@ -401,6 +417,7 @@ export async function compileCInternal( const dh = opts.dh ?? false; const pki = opts.pki ?? false; const mbedtls = tls || cipher || ecdh || dh || pki; + const brotli = (opts.zlib ?? false) && opts.brotli === true; const driver = resolveCc(); const darwinDebugSymbols = needsDarwinDebugSymbols( targetPlatform(driver), @@ -640,6 +657,9 @@ export async function compileCInternal( let tlsArchive = mbedtls ? tlsArchivePath(sanitize, driver, vendorBuildIdentity, vendorCacheRoot) : null; + let brotliArchive = brotli + ? brotliArchivePath(sanitize, driver, vendorBuildIdentity, vendorCacheRoot) + : null; // ours would collide; see scr_regex.c) — the standalone objects are for // static builds only. @@ -677,6 +697,23 @@ export async function compileCInternal( : await stageVendorInputs(materialize, join(stageRoot, "tls")); tlsArchive = paths[0]!; } + if (brotli) { + const cachedArchive = brotliArchivePath( + sanitize, + driver, + vendorBuildIdentity, + materializeCacheRoot, + ); + protectCachedArtifact(cacheWarmPaths, cachedArchive); + const materialize = async (): Promise => [ + await ensureBrotliArchive(sanitize, driver, vendorBuildIdentity, materializeCacheRoot), + ]; + const paths = + stageRoot === undefined + ? await materialize() + : await stageVendorInputs(materialize, join(stageRoot, "brotli")); + brotliArchive = paths[0]!; + } if (regex) { for (const object of lreObjectPaths( sanitize, @@ -763,6 +800,7 @@ export async function compileCInternal( lreObjects, zlibObjects, tlsArchive, + brotliArchive, }), // A .ll program TU (the LLVM backend) deliberately carries no target // triple (byte-stable output; clang supplies the host/SCRIPTC_TARGET diff --git a/packages/compiler/src/backend/native/runtime-inputs.ts b/packages/compiler/src/backend/native/runtime-inputs.ts index 6fb51fd32..c7c5bc32b 100644 --- a/packages/compiler/src/backend/native/runtime-inputs.ts +++ b/packages/compiler/src/backend/native/runtime-inputs.ts @@ -3,7 +3,7 @@ import { createRequire } from "node:module"; import { readdir, readFile, realpath, stat } from "node:fs/promises"; import { basename, dirname, extname, join, relative, resolve } from "node:path"; import { fileURLToPath } from "node:url"; -import { MBEDTLS_VERSION, QJS_COMMIT, ZLIB_VERSION } from "../vendor-inputs.js"; +import { BROTLI_VERSION, MBEDTLS_VERSION, QJS_COMMIT, ZLIB_VERSION } from "../vendor-inputs.js"; import { stableTestMemo } from "./session.js"; const implementationPath = fileURLToPath(import.meta.url); @@ -134,6 +134,7 @@ async function runtimeFingerprintFresh(rtDir: string): Promise { .update(QJS_COMMIT) .update(MBEDTLS_VERSION) .update(ZLIB_VERSION) + .update(BROTLI_VERSION) .update("\0backend-recipe\0"); for (const path of NATIVE_RECIPE_IMPLEMENTATION_PATHS) { h.update(basename(path)) @@ -164,6 +165,7 @@ async function runtimeFingerprintInputGroups( { label: "quickjs-ng", dir: join(rtDir, "..", "vendor", "quickjs-ng") }, { label: "mbedtls", dir: join(rtDir, "..", "vendor", "mbedtls") }, { label: "zlib", dir: join(rtDir, "..", "vendor", "zlib") }, + { label: "brotli", dir: join(rtDir, "..", "vendor", "brotli", "c") }, { label: "curl", dir: join(rtDir, "..", "vendor", "curl") }, ].map(async (group) => { const names = (await nativeSourceFiles(group.dir, true)) diff --git a/packages/compiler/src/backend/native/vendor.ts b/packages/compiler/src/backend/native/vendor.ts index cf7b3a68d..b6084d5c4 100644 --- a/packages/compiler/src/backend/native/vendor.ts +++ b/packages/compiler/src/backend/native/vendor.ts @@ -6,6 +6,9 @@ import { resolvedToolIdentity } from "./tool-identity.js"; export const { vendorEngineDir, vendorTlsDir, + vendorBrotliDir, + brotliArchivePath, + ensureBrotliArchive, vendorBuildCacheRoot, vendorCacheTargetFlavor, vendorCacheBuildIdentity, diff --git a/packages/compiler/src/backend/runtime-pack-core.ts b/packages/compiler/src/backend/runtime-pack-core.ts index 75953be59..49165d8df 100644 --- a/packages/compiler/src/backend/runtime-pack-core.ts +++ b/packages/compiler/src/backend/runtime-pack-core.ts @@ -34,7 +34,7 @@ interface RuntimePackUnit { } interface RuntimePackArchive extends RuntimePackArtifact { - id: "quickjs" | "libregexp" | "zlib" | "mbedtls"; + id: "quickjs" | "libregexp" | "zlib" | "brotli" | "mbedtls"; predicate: RuntimePredicate; } @@ -93,6 +93,7 @@ export interface RuntimeFeatureSet extends NativeLinkFeatures { builtinValues: boolean; warningReplace: boolean; stdioExtended: boolean; + brotli: boolean; nativeFetch: boolean; netEffective: boolean; httpEffective: boolean; @@ -291,6 +292,7 @@ export function effectiveRuntimeFeatures( builtinValues: features.builtinValues === true, warningReplace: features.warningReplace === true, stdioExtended: features.stdioExtended === true, + brotli: features.brotli === true, nativeFetch, netEffective, httpEffective, diff --git a/packages/compiler/src/backend/target-cpu.test.ts b/packages/compiler/src/backend/target-cpu.test.ts new file mode 100644 index 000000000..428caee32 --- /dev/null +++ b/packages/compiler/src/backend/target-cpu.test.ts @@ -0,0 +1,51 @@ +import { expect, test } from "vitest"; +import { + isTargetCpuOption, + targetCpuAttribute, + targetCpuField, + targetCpuKeyParts, + targetCpuTargetRefusal, + x86Level, +} from "./target-cpu.js"; + +const V2 = ["cx16", "lahf_lm", "popcnt", "pni", "sse4_1", "sse4_2", "ssse3"]; +const V3 = ["avx", "avx2", "bmi1", "bmi2", "f16c", "fma", "abm", "movbe", "xsave"]; +const V4 = ["avx512f", "avx512bw", "avx512cd", "avx512dq", "avx512vl"]; +const level = (flags: string[]) => x86Level((flag) => flags.includes(flag)); + +test("a host's level is the highest one whose features and lower levels' features it has", () => { + expect(level([])).toBe("baseline"); + expect(level(V2)).toBe("x86-64-v2"); + expect(level([...V2, ...V3])).toBe("x86-64-v3"); + expect(level([...V2, ...V3, ...V4])).toBe("x86-64-v4"); + // AVX-512 without BMI2 is still v2. + expect(level([...V2, ...V3.filter((f) => f !== "bmi2"), ...V4])).toBe("x86-64-v2"); + expect(level([...V3, ...V4])).toBe("baseline"); +}); + +test("the baseline adds no key part, attribute or option field", () => { + for (const cpu of [undefined, "baseline"] as const) { + expect(targetCpuKeyParts(cpu)).toEqual([]); + expect(targetCpuAttribute(cpu)).toBe(""); + expect(targetCpuField(cpu)).toEqual({}); + expect(targetCpuTargetRefusal(cpu, "linux", "arm64")).toBeNull(); + } + expect(targetCpuKeyParts("x86-64-v3")).toEqual(["target-cpu-x86-64-v3"]); + expect(targetCpuAttribute("x86-64-v4")).toBe(' "target-cpu"="x86-64-v4"'); + expect(targetCpuField("x86-64-v2")).toEqual({ targetCpu: "x86-64-v2" }); +}); + +test("a level is refused for targets that are not x86-64", () => { + expect(targetCpuTargetRefusal("x86-64-v3", "linux", "x64")).toBeNull(); + expect(targetCpuTargetRefusal("x86-64-v3", "darwin", "arm64")).toBe( + "--target-cpu=x86-64-v3 requires an x86-64 target", + ); + expect(targetCpuTargetRefusal("x86-64-v3", "wasi", "x64")).not.toBeNull(); +}); + +test("the option accepts the levels and native", () => { + for (const value of ["baseline", "x86-64-v2", "x86-64-v3", "x86-64-v4", "native"]) + expect(isTargetCpuOption(value)).toBe(true); + for (const value of ["x86-64", "haswell", "", undefined]) + expect(isTargetCpuOption(value)).toBe(false); +}); diff --git a/packages/compiler/src/backend/target-cpu.ts b/packages/compiler/src/backend/target-cpu.ts new file mode 100644 index 000000000..51db87bbb --- /dev/null +++ b/packages/compiler/src/backend/target-cpu.ts @@ -0,0 +1,118 @@ +import { execFileSync } from "node:child_process"; +import { readFileSync } from "node:fs"; + +/** The x86-64 microarchitecture levels an executable may require + * (`--target-cpu`). `baseline` is the x86-64 baseline every release build + * targets; the other levels are LLVM's `x86-64-v2` to `x86-64-v4`. */ +export type TargetCpu = "baseline" | "x86-64-v2" | "x86-64-v3" | "x86-64-v4"; + +/** The values `--target-cpu` accepts: a level, or `native` for the highest + * level the build host supports. */ +export const TARGET_CPU_OPTIONS = ["baseline", "x86-64-v2", "x86-64-v3", "x86-64-v4", "native"]; + +export function isTargetCpuOption(value: unknown): value is TargetCpu | "native" { + return typeof value === "string" && TARGET_CPU_OPTIONS.includes(value); +} + +/** The CPU features each level adds to the one below it, as Linux names + * them in /proc/cpuinfo (`pni` is SSE3, `abm` includes LZCNT). */ +const LEVEL_FLAGS: readonly [TargetCpu, readonly string[]][] = [ + ["x86-64-v2", ["cx16", "lahf_lm", "popcnt", "pni", "sse4_1", "sse4_2", "ssse3"]], + ["x86-64-v3", ["avx", "avx2", "bmi1", "bmi2", "f16c", "fma", "abm", "movbe", "xsave"]], + ["x86-64-v4", ["avx512f", "avx512bw", "avx512cd", "avx512dq", "avx512vl"]], +]; + +/** The macOS `machdep.cpu` spellings of the same features. */ +const DARWIN_FLAGS: Readonly> = { + cx16: "CX16", + lahf_lm: "LAHF", + popcnt: "POPCNT", + pni: "SSE3", + sse4_1: "SSE4.1", + sse4_2: "SSE4.2", + ssse3: "SSSE3", + avx: "AVX1.0", + avx2: "AVX2", + bmi1: "BMI1", + bmi2: "BMI2", + f16c: "F16C", + fma: "FMA", + abm: "LZCNT", + movbe: "MOVBE", + xsave: "XSAVE", + avx512f: "AVX512F", + avx512bw: "AVX512BW", + avx512cd: "AVX512CD", + avx512dq: "AVX512DQ", + avx512vl: "AVX512VL", +}; + +/** The highest level whose features (and every lower level's) are all in + * `has`. */ +export function x86Level(has: (flag: string) => boolean): TargetCpu { + let level: TargetCpu = "baseline"; + for (const [next, flags] of LEVEL_FLAGS) { + if (!flags.every(has)) break; + level = next; + } + return level; +} + +/** The highest level the build host supports, or null when the host is not + * an x86-64 Linux or macOS machine. */ +export function hostTargetCpu( + platform: string = process.platform, + arch: string = process.arch, +): TargetCpu | null { + if (arch !== "x64") return null; + try { + if (platform === "linux") { + const info = readFileSync("/proc/cpuinfo", "utf8"); + const line = /^flags\s*:(.*)$/m.exec(info); + if (!line) return null; + const flags = new Set(line[1]!.trim().split(/\s+/)); + return x86Level((flag) => flags.has(flag)); + } + if (platform === "darwin") { + const text = execFileSync( + "sysctl", + ["-n", "machdep.cpu.features", "machdep.cpu.leaf7_features", "machdep.cpu.extfeatures"], + { encoding: "utf8" }, + ); + const flags = new Set(text.trim().split(/\s+/)); + return x86Level((flag) => flags.has(DARWIN_FLAGS[flag]!)); + } + } catch { + return null; + } + return null; +} + +/** Cache-key parts for a target level; empty for the baseline so existing + * keys are unchanged. */ +export function targetCpuKeyParts(cpu: TargetCpu | undefined): string[] { + return cpu === undefined || cpu === "baseline" ? [] : [`target-cpu-${cpu}`]; +} + +/** The function attribute that makes LLVM generate code for the level, or + * "" for the baseline. */ +export function targetCpuAttribute(cpu: TargetCpu | undefined): string { + return cpu === undefined || cpu === "baseline" ? "" : ` "target-cpu"="${cpu}"`; +} + +/** The options field for a level: omitted for the baseline. */ +export function targetCpuField(cpu: TargetCpu | undefined): { targetCpu?: TargetCpu } { + return cpu === undefined || cpu === "baseline" ? {} : { targetCpu: cpu }; +} + +/** The error for a level on a target that is not x86-64, or null. */ +export function targetCpuTargetRefusal( + cpu: TargetCpu | undefined, + platform: string, + architecture: string, +): string | null { + if (cpu === undefined || cpu === "baseline") return null; + if (architecture !== "x64" || platform === "wasi") + return `--target-cpu=${cpu} requires an x86-64 target`; + return null; +} diff --git a/packages/compiler/src/backend/vendor-archives.ts b/packages/compiler/src/backend/vendor-archives.ts index daa7e5eaa..dbcaf2d36 100644 --- a/packages/compiler/src/backend/vendor-archives.ts +++ b/packages/compiler/src/backend/vendor-archives.ts @@ -18,6 +18,7 @@ import { QJS_COMMIT, MBEDTLS_VERSION, ZLIB_VERSION, + BROTLI_VERSION, LRE_SOURCES, ZLIB_SOURCES, } from "./vendor-inputs.js"; @@ -25,6 +26,7 @@ export { QJS_COMMIT, MBEDTLS_VERSION, ZLIB_VERSION, + BROTLI_VERSION, LRE_SOURCES, ZLIB_SOURCES, } from "./vendor-inputs.js"; @@ -418,9 +420,98 @@ export function createVendorArchives(context: VendorArchiveContext) { return archive; } + function vendorBrotliDir(): string { + return join(runtimeSrcDir(), "..", "vendor", "brotli", "c"); + } + + function brotliArchivePath( + sanitize: boolean, + driver: CcDriver, + buildIdentity: string, + cacheRoot: string = vendorBuildCacheRoot(), + ): string { + const flavor = `${sanitize ? "asan" : "plain"}-${vendorCacheTargetFlavor(driver)}-${buildIdentity}`; + return join(cacheRoot, `brotli-${BROTLI_VERSION}-${flavor}`, "libbrotli.a"); + } + + /** The brotli archive for one flavor, compiled lazily on the first + * Brotli-using build and cached under + * /vendor/brotli----/libbrotli.a, + * with the mbedTLS archive's recipe: per-TU compiles of c/common, c/dec + * and c/enc against c/include, then one `ar rcs`. dec/ and enc/ share + * file names, so each object is named after its path (dec-static_init.o). */ + async function ensureBrotliArchive( + sanitize: boolean, + driver: CcDriver, + buildIdentity: string, + cacheRoot: string = vendorBuildCacheRoot(), + ): Promise { + const flavor = `${sanitize ? "asan" : "plain"}-${vendorCacheTargetFlavor(driver)}-${buildIdentity}`; + const compileArgv = isZigDriver(driver) ? driver.argv : ["clang"]; + const arArgv = isZigDriver(driver) ? [...driver.argv.slice(0, 1), "ar"] : ["ar"]; + const vendor = vendorBrotliDir(); + const archive = brotliArchivePath(sanitize, driver, buildIdentity, cacheRoot); + if (await validVendorArtifact(archive)) return archive; + + await mkdir(cacheRoot, { recursive: true }); + const buildDir = await mkdtemp(join(tmpdir(), `scriptc-vendor-brotli-${flavor}-`)); + try { + const sources = ( + await Promise.all( + ["common", "dec", "enc"].map(async (dir) => + (await readdir(join(vendor, dir))) + .filter((name) => !name.startsWith(".") && name.endsWith(".c")) + .map((name) => `${dir}/${name}`), + ), + ) + ) + .flat() + .sort(); + const object = (src: string): string => + join(buildDir, `${src.replaceAll("/", "-").replace(/\.c$/, "")}.o`); + const cflags = [ + "-std=c11", + ...driver.targetArgs, + ...(sanitize ? ["-O1", "-fsanitize=address"] : ["-Os"]), + "-I", + join(vendor, "include"), + ]; + const width = availableParallelism(); + for (let i = 0; i < sources.length; i += width) { + await Promise.all( + sources + .slice(i, i + width) + .map((src) => + execFileAsync(compileArgv[0] ?? "clang", [ + ...compileArgv.slice(1), + ...cflags, + "-c", + join(vendor, src), + "-o", + object(src), + ]), + ), + ); + } + await execFileAsync(arArgv[0] ?? "ar", [ + ...arArgv.slice(1), + "rcs", + join(buildDir, "libbrotli.a"), + ...sources.map(object), + ]); + await publishVendorArtifact(join(buildDir, "libbrotli.a"), archive); + } finally { + await rm(buildDir, { recursive: true, force: true }); + } + return archive; + } + return { vendorEngineDir, vendorTlsDir, + vendorBrotliDir, + brotliArchivePath, + ensureBrotliArchive, vendorBuildCacheRoot, vendorCacheTargetFlavor, vendorCacheBuildIdentity, diff --git a/packages/compiler/src/backend/vendor-inputs.ts b/packages/compiler/src/backend/vendor-inputs.ts index 3d2710fa0..a9d13e2f0 100644 --- a/packages/compiler/src/backend/vendor-inputs.ts +++ b/packages/compiler/src/backend/vendor-inputs.ts @@ -1,7 +1,9 @@ -/** The pinned QuickJS, mbedTLS, and zlib inputs used by native recipes. */ +/** The pinned QuickJS, mbedTLS, zlib, and brotli inputs used by native recipes. */ export const QJS_COMMIT = "3c8f3d68953955950074c41c6e4d999562ae82a7"; export const MBEDTLS_VERSION = "3.6.7"; export const ZLIB_VERSION = "1.3.1"; +/** The brotli release Node v24.22.0 bundles (packages/runtime/vendor/brotli). */ +export const BROTLI_VERSION = "1.2.0"; /** Exact translation-unit membership shared by cache builds and external * source-pack recipes. */ export const LRE_SOURCES = ["libregexp.c", "libunicode.c"] as const; diff --git a/packages/compiler/src/cli/command.ts b/packages/compiler/src/cli/command.ts index 3285aa7fa..57b15349e 100644 --- a/packages/compiler/src/cli/command.ts +++ b/packages/compiler/src/cli/command.ts @@ -15,6 +15,13 @@ import { buildEnvelope } from "../diagnostics/envelope.js"; import { renderWarnings } from "../diagnostics/render.js"; import { isPerformanceCode, renderPerformanceWarnings } from "../diagnostics/dynamic-tier.js"; import { isNativeOptimization } from "../backend/optimization.js"; +import { + hostTargetCpu, + isTargetCpuOption, + TARGET_CPU_OPTIONS, + targetCpuField, + type TargetCpu, +} from "../backend/target-cpu.js"; import { setProvenanceSources } from "../frontend/provenance-registry.js"; import type { CliHost, NativeCacheWarmProfile } from "./host.js"; import { resolveOutputOptions } from "./output-options.js"; @@ -96,6 +103,7 @@ async function main(args: string[], host: CliHost): Promise { values.strip || values["windows-subsystem"] !== undefined || values["detached-exit"] || + values["target-cpu"] !== undefined || values["profile-generate"] !== undefined || values["profile-use"] !== undefined || values.sparse || @@ -154,6 +162,7 @@ async function main(args: string[], host: CliHost): Promise { values.sanitize || values["windows-subsystem"] !== undefined || values["detached-exit"] || + values["target-cpu"] !== undefined || values["profile-generate"] !== undefined || values["profile-use"] !== undefined || (values["npm-static"] ?? []).length > 0 || @@ -210,6 +219,7 @@ async function main(args: string[], host: CliHost): Promise { values.ffi !== undefined || values["windows-subsystem"] !== undefined || values["detached-exit"] || + values["target-cpu"] !== undefined || values["profile-generate"] !== undefined || values["profile-use"] !== undefined || (values["npm-static"] ?? []).length > 0 || @@ -218,7 +228,7 @@ async function main(args: string[], host: CliHost): Promise { values["explain-dynamic"] !== undefined ) { fail( - "scriptc build --lib takes no --backend/--emit/--print/--optimization/--strip/--windows-subsystem/--detached-exit/--profile-generate/--profile-use/--npm-static/--ffi/--external-types/--tier/--explain-dynamic: the profile pins the emission and optimization, npm imports are judged automatically, outbound FFI belongs to executable builds, external type mappings belong to coverage, and library artifacts are static-tier only", + "scriptc build --lib takes no --backend/--emit/--print/--optimization/--strip/--windows-subsystem/--detached-exit/--target-cpu/--profile-generate/--profile-use/--npm-static/--ffi/--external-types/--tier/--explain-dynamic: the profile pins the emission and optimization, npm imports are judged automatically, outbound FFI belongs to executable builds, external type mappings belong to coverage, and library artifacts are static-tier only", ); } const profilePath = resolve(profileArg); @@ -261,6 +271,9 @@ async function main(args: string[], host: CliHost): Promise { if (command === "coverage" && values.strip) { fail(`--strip is a build/run option\n\n${USAGE}`); } + if (command === "coverage" && values["target-cpu"] !== undefined) { + fail(`--target-cpu is a build/run option\n\n${USAGE}`); + } if (command === "coverage" && values["detached-exit"]) { fail(`--detached-exit is a build/run option\n\n${USAGE}`); } @@ -377,6 +390,19 @@ async function main(args: string[], host: CliHost): Promise { if (windowsSubsystem !== undefined && command === "coverage") { fail(`--windows-subsystem is only supported for executable builds\n\n${USAGE}`); } + const targetCpuOption = values["target-cpu"]; + if (targetCpuOption !== undefined && !isTargetCpuOption(targetCpuOption)) { + fail( + `unknown target CPU "${targetCpuOption}" (supported: ${TARGET_CPU_OPTIONS.join(", ")})\n\n${USAGE}`, + ); + } + let targetCpu: TargetCpu | undefined = targetCpuOption === "native" ? undefined : targetCpuOption; + if (targetCpuOption === "native") { + const level = hostTargetCpu(); + if (level === null) + fail(`--target-cpu=native needs an x86-64 Linux or macOS build host; name a level instead`); + targetCpu = level; + } const output = command === "coverage" ? null @@ -498,6 +524,7 @@ async function main(args: string[], host: CliHost): Promise { ...(values.strip ? { strip: true } : {}), ...(windowsSubsystem !== undefined ? { windowsSubsystem } : {}), ...(values["detached-exit"] ? { detachedExit: true } : {}), + ...targetCpuField(targetCpu), // The instrumented program resolves a relative pattern against its own // working directory; resolve it here, where the user wrote it. ...(values["profile-generate"] === undefined diff --git a/packages/compiler/src/cli/usage.ts b/packages/compiler/src/cli/usage.ts index c4d07656a..01afbdd41 100644 --- a/packages/compiler/src/cli/usage.ts +++ b/packages/compiler/src/cli/usage.ts @@ -54,6 +54,12 @@ Options: a helper process so the parent sees the exit sooner. The helper keeps the executable mapped and its memory charged for up to ~100 ms after exit (opt in; --emit=exe only) + --target-cpu + x86-64: compile the program's code for a CPU level + (default: baseline, which runs on any x86-64 CPU). The + executable then requires that level: v3 adds AVX2, BMI2 + and FMA, v4 adds AVX-512. native uses the build host's + level. The runtime keeps its baseline code --profile-generate Linux: instrument the executable for profile-guided optimization. Each run writes a raw profile to the @@ -123,6 +129,7 @@ export const CLI_OPTIONS = { strip: { type: "boolean", default: false }, "windows-subsystem": { type: "string" }, "detached-exit": { type: "boolean", default: false }, + "target-cpu": { type: "string" }, "profile-generate": { type: "string" }, "profile-use": { type: "string" }, sparse: { type: "boolean", default: false }, diff --git a/packages/compiler/src/compile-types.ts b/packages/compiler/src/compile-types.ts index 9ecd75974..c50931c6a 100644 --- a/packages/compiler/src/compile-types.ts +++ b/packages/compiler/src/compile-types.ts @@ -1,3 +1,4 @@ +import type { TargetCpu } from "./backend/target-cpu.js"; import type { WindowsSubsystem } from "./backend/targets.js"; import type { NativeLinkInfo } from "./backend/native-link-info.js"; import type { NativeOptimization } from "./backend/optimization.js"; @@ -36,6 +37,12 @@ export interface CompileBaseOptions { * executable mapped and the memory charged for up to ~100 ms after exit. * Executables only; no effect on other platforms. */ detachedExit?: boolean; + /** The x86-64 microarchitecture level the executable's code may require + * (`x86-64-v2` to `x86-64-v4`). The program's functions are compiled for + * that level, and the executable then runs only on CPUs that support it. + * Unset or `baseline`, the code runs on any x86-64 CPU. x86-64 targets + * only; the runtime pack keeps its baseline code. */ + targetCpu?: TargetCpu; /** Instrument the executable for profile-guided optimization. Each run * writes a raw profile to this path pattern (`%p` expands to the process * id; `LLVM_PROFILE_FILE` overrides the pattern at run time). Linux diff --git a/packages/compiler/src/executable/executable-cache.test.ts b/packages/compiler/src/executable/executable-cache.test.ts index 4aaa86e0d..afae8b2c1 100644 --- a/packages/compiler/src/executable/executable-cache.test.ts +++ b/packages/compiler/src/executable/executable-cache.test.ts @@ -237,6 +237,8 @@ test("early executable keys isolate compile modes, paths, implementation, checke { ...f.options, optimization: "dev" }, { ...f.options, optimization: "speed" }, { ...f.options, detachedExit: true }, + { ...f.options, targetCpu: "x86-64-v3" }, + { ...f.options, targetCpu: "x86-64-v4" }, { ...f.options, profile: "profile-generate:/tmp/%p.profraw" }, { ...f.options, profile: "profile-use:digest" }, { ...f.options, checker: "tsc-ts-executable-identity" }, diff --git a/packages/compiler/src/executable/executable-cache.ts b/packages/compiler/src/executable/executable-cache.ts index 10fcae7c5..34b162be3 100644 --- a/packages/compiler/src/executable/executable-cache.ts +++ b/packages/compiler/src/executable/executable-cache.ts @@ -18,6 +18,7 @@ import { compilerReleaseVersion } from "../library/sidecar.js"; import { nativeArtifactDependenciesStillMatch } from "../backend/native/artifact-stamps.js"; import { type NativeArtifactDependency } from "../backend/native/contracts.js"; import { optimizationKeyParts } from "../backend/optimization.js"; +import { type TargetCpu, targetCpuKeyParts } from "../backend/target-cpu.js"; import { privateSiblingPath } from "../backend/build-cache.js"; import type { CompilerImplementationDependency } from "../library/compiler-self-identity.js"; import { @@ -62,6 +63,7 @@ export interface EarlyExecutableNativeFeatures { warningReplace?: boolean; stdioExtended?: boolean; zlib: boolean; + brotli?: boolean; assert: boolean; inspect: boolean; dynInvoke: boolean; @@ -140,6 +142,8 @@ export interface EarlyExecutableCacheOptions { windowsSubsystem?: "gui"; /** Omitted unless --detached-exit is set. */ detachedExit?: true; + /** Omitted for the x86-64 baseline (`--target-cpu`). */ + targetCpu?: TargetCpu; /** Omitted without --profile-generate/--profile-use; otherwise the * pattern, or the digest of the profile's bytes. */ profile?: string; @@ -283,6 +287,7 @@ function cacheKey(options: EarlyExecutableCacheOptions): string { ...(options.strip ? ["strip"] : []), ...(options.windowsSubsystem === "gui" ? ["windows-subsystem-gui"] : []), ...(options.detachedExit ? ["detached-exit"] : []), + ...targetCpuKeyParts(options.targetCpu), ...(options.profile !== undefined ? [options.profile] : []), ...(options.checker !== undefined ? [`checker:${options.checker}`] : []), ...(options.youngNursery ? ["young-nursery"] : []), @@ -325,6 +330,7 @@ function routeKey(options: Omit> = { unzip: "zlib.unzipCb", }; +/* Node's BROTLI_DECODE and BROTLI_ENCODE modes. */ +const BROTLI_DECODE = 8; +const BROTLI_ENCODE = 9; + +/** The Brotli one-shots: every form takes the options entries. */ +const BROTLI_SYNC_MEMBERS: ReadonlySet = new Set([ + "brotliCompressSync", + "brotliDecompressSync", +]); +const BROTLI_CALLBACK_MEMBERS: ReadonlySet = new Set([ + "brotliCompress", + "brotliDecompress", +]); + +/** A Brotli mode connects the codec (scr_brotli.c) to the zlib engine + * before any module initializer runs. */ +function noteBrotliMode(lowerer: Lowerer, mode: number, loc: SrcLoc): void { + if (mode !== BROTLI_DECODE && mode !== BROTLI_ENCODE) return; + const installs = (stmt: IrStmt): boolean => + stmt.kind === "exprStmt" && + stmt.expr.kind === "libCall" && + stmt.expr.fn === "zlib.brotliInstall"; + if (lowerer.mainPrelude.some(installs)) return; + lowerer.mainPrelude.push({ + kind: "exprStmt", + expr: { kind: "libCall", fn: "zlib.brotliInstall", args: [], type: VOID, loc }, + loc, + }); +} + const ZLIB_STREAM_CLASS = "%Transform"; const ZLIB_STREAM_T: IrType = { kind: "object", className: ZLIB_STREAM_CLASS }; @@ -115,6 +146,7 @@ export function lowerZlibStreamNew( } const options = args[0] !== undefined ? zlibOptionsValue(lowerer, args[0], what, loc) : dynUndefinedExpr(loc); + noteBrotliMode(lowerer, mode, loc); return { kind: "libCall", fn: "zlib.streamNew", @@ -154,8 +186,8 @@ function isZlibFallbackDecl(lowerer: Lowerer, d: ts.Node): boolean { return false; } -/** True when `access` names a member the zlib stream base class declares - * (bytesWritten, flush, params, close, reset). */ +/** True when `access` names a member the zlib stream base classes declare + * (bytesWritten, flush, close and reset on ZlibBase; params on Zlib). */ export function isZlibStreamMember(lowerer: Lowerer, access: ts.PropertyAccessExpression): boolean { const symbol = lowerer.checker.getSymbolAtLocation(access.name); if (!symbol) return false; @@ -163,7 +195,7 @@ export function isZlibStreamMember(lowerer: Lowerer, access: ts.PropertyAccessEx (d) => d.parent !== undefined && ts.isClassDeclaration(d.parent) && - d.parent.name?.text === "ZlibBase" && + (d.parent.name?.text === "ZlibBase" || d.parent.name?.text === "Zlib") && isZlibFallbackDecl(lowerer, d.parent), ); } @@ -281,12 +313,17 @@ const ZLIB_ONE_SHOT_MODES: Readonly> = { deflateRaw: 5, inflateRaw: 6, unzip: 7, + brotliDecompressSync: BROTLI_DECODE, + brotliCompressSync: BROTLI_ENCODE, + brotliDecompress: BROTLI_DECODE, + brotliCompress: BROTLI_ENCODE, }; /** True for a zlib callback one-shot util.promisify converts (deflate, - * inflate, deflateRaw, inflateRaw, gzip, gunzip and unzip). */ + * inflate, deflateRaw, inflateRaw, gzip, gunzip, unzip, brotliCompress and + * brotliDecompress). */ export function isPromisifiedZlibMember(member: string): boolean { - return ZLIB_CALLBACK_FNS[member] !== undefined; + return ZLIB_CALLBACK_FNS[member] !== undefined || BROTLI_CALLBACK_MEMBERS.has(member); } /** A call through `promisify(zlib.gzip)` and the other callback one-shots: @@ -311,6 +348,7 @@ export function lowerPromisifiedZlibCall( ); } const input = zlibInput(lowerer, expr.arguments.nodes[0]!, loc); + noteBrotliMode(lowerer, ZLIB_ONE_SHOT_MODES[member]!, loc); return { kind: "libCall", fn: input.dyn ? "zlib.promiseDyn" : "zlib.promise", @@ -334,6 +372,8 @@ const ZLIB_STREAM_FACTORIES: Readonly> = { createDeflateRaw: 5, createInflateRaw: 6, createUnzip: 7, + createBrotliDecompress: BROTLI_DECODE, + createBrotliCompress: BROTLI_ENCODE, }; export function lowerZlibModuleCall( @@ -356,6 +396,9 @@ export function lowerZlibModuleCall( loc, ); } + if (BROTLI_SYNC_MEMBERS.has(bi.member) || BROTLI_CALLBACK_MEMBERS.has(bi.member)) { + return lowerBrotliOneShot(lowerer, expr, bi.member, loc); + } const syncFn = ZLIB_SYNC_FNS[bi.member]; if (syncFn !== undefined) { if (expr.arguments.nodes.length === 0 || expr.arguments.nodes.length > 2) { @@ -502,6 +545,57 @@ export function lowerZlibModuleCall( throw new InternalCompilerError(`unhandled lowered zlib member ${bi.member}`); } +/** brotliCompressSync(data[, options]), brotliCompress(data[, options], + * callback) and the decompress pair: the options entries with Node's + * BROTLI_ENCODE or BROTLI_DECODE mode, an absent options value passing + * undefined. */ +function lowerBrotliOneShot( + lowerer: Lowerer, + expr: ts.CallExpression, + member: string, + loc: SrcLoc, +): IrExpr { + const args = expr.arguments.nodes; + const mode = ZLIB_ONE_SHOT_MODES[member]!; + const sync = BROTLI_SYNC_MEMBERS.has(member); + if (sync ? args.length === 0 || args.length > 2 : args.length !== 2 && args.length !== 3) { + lowerer.noLowering( + `zlib.${member} with ${args.length} arguments`, + expr, + sync + ? `${member}(data) and ${member}(data, options) are supported` + : `${member}(data, callback) and ${member}(data, options, callback) are supported`, + ); + } + const input = zlibInput(lowerer, args[0]!, loc); + const withOptions = sync ? args.length === 2 : args.length === 3; + const options = withOptions + ? zlibOptionsValue(lowerer, args[1]!, `zlib.${member}`, loc) + : dynUndefinedExpr(loc); + noteBrotliMode(lowerer, mode, loc); + if (sync) { + return { + kind: "libCall", + fn: input.dyn ? "zlib.syncOptsDyn" : "zlib.syncOpts", + args: [numLit(mode, loc), input.value, options], + type: BYTES_U8, + loc, + }; + } + return { + kind: "libCall", + fn: input.dyn ? "zlib.cbOptsDyn" : "zlib.cbOpts", + args: [ + numLit(mode, loc), + input.value, + options, + errorFirstBytesCallback(lowerer, args[withOptions ? 2 : 1]!, "zlib"), + ], + type: VOID, + loc, + }; +} + /** The class name of a zlib stream mode (Node's constructor name). */ export function zlibClassName(mode: number): string { for (const [name, m] of ZLIB_STREAM_MODES) if (m === mode) return name; diff --git a/packages/compiler/src/frontend/lowering/builtins/filesystem-calls.ts b/packages/compiler/src/frontend/lowering/builtins/filesystem-calls.ts index d147a6208..0bbc3b3fa 100644 --- a/packages/compiler/src/frontend/lowering/builtins/filesystem-calls.ts +++ b/packages/compiler/src/frontend/lowering/builtins/filesystem-calls.ts @@ -265,7 +265,7 @@ export function lowerFsPromisesOpenCall( "use open(path[, stringFlags[, numericMode]])", ); } - const path = lowerer.lowerExprExpecting(expr.arguments.nodes[0]!, STRING); + const path = lowerFsPath(lowerer, expr.arguments.nodes[0]!); const defaultFlags: IrExpr = { kind: "strLit", value: "r", type: STRING, loc }; const defaultMode: IrExpr = { kind: "numLit", value: 0o666, type: F64, loc }; const flags = expr.arguments.nodes[1] @@ -705,7 +705,7 @@ export function lowerFsPromisesEncodedRead( ) return null; } - const path = lowerer.lowerExprExpecting(expr.arguments.nodes[0]!, STRING); + const path = lowerFsPath(lowerer, expr.arguments.nodes[0]!); const encoding: IrExpr = optionsType.kind === "string" ? lowerer.lowerExprExpecting(options, STRING) @@ -853,7 +853,7 @@ export function lowerFsPromisesMkdirCall( ); } const { recursive, modeNode } = options; - const path = lowerer.lowerExprExpecting(expr.arguments.nodes[0]!, STRING); + const path = lowerFsPath(lowerer, expr.arguments.nodes[0]!); const mode: IrExpr | null = modeNode ? lowerer.lowerExprExpecting(modeNode, F64) : null; const type: IrType = { kind: "promise", inner: VOID }; if (!recursive) { diff --git a/packages/compiler/src/frontend/lowering/builtins/fs-glob.ts b/packages/compiler/src/frontend/lowering/builtins/fs-glob.ts index f988c204d..4d88cd96e 100644 --- a/packages/compiler/src/frontend/lowering/builtins/fs-glob.ts +++ b/packages/compiler/src/frontend/lowering/builtins/fs-glob.ts @@ -22,7 +22,10 @@ import { builtinImportOf } from "./module-bindings.js"; * lib/internal/fs/glob.js). The pattern and options cross as dyn values so * the runtime validates them in Node's order. The result form (strings or * Dirent rows) comes from the call's mapped result type, so withFileTypes - * must be statically known; the runtime checks that the option agrees. */ + * must be statically known; the runtime checks that the option agrees. + * Because of that check, the form follows the checker's resolved overload + * even where an untyped options argument leaves the overload undecided + * (dynamicOverloadChoice). */ /** The interned Dirent record array (type-mapper.ts), or null. */ function direntArray(lowerer: Lowerer, type: IrType | null | undefined): boolean { @@ -67,7 +70,7 @@ export function lowerFsGlobSyncCall( loc: SrcLoc, ): IrExpr { const args = globArgs(lowerer, call, "fs.globSync"); - const callType = lowerer.mapTypeOf(lowerer.typeOf(call)); + const callType = lowerer.mapTypeOf(lowerer.checker.getTypeAtLocation(call)); const types = direntArray(lowerer, callType); if (types) fenceDirentExclude(lowerer, call, "fs.globSync"); if (!types && !(callType?.kind === "array" && callType.elem.kind === "string")) { @@ -132,7 +135,9 @@ export function lowerFspGlobCall(lowerer: Lowerer, call: ts.CallExpression, loc: } const args = globArgs(lowerer, call, "fs/promises glob"); // The async iterator's yielded type (its first type argument). - const yielded = lowerer.checker.getTypeArguments(lowerer.typeOf(call) as ts.TypeReference)[0]; + const yielded = lowerer.checker.getTypeArguments( + lowerer.checker.getTypeAtLocation(call) as ts.TypeReference, + )[0]; const element = yielded ? lowerer.mapTypeOf(yielded) : null; const rows: IrType | null = element ? { kind: "array", elem: element } : null; const types = direntArray(lowerer, rows); diff --git a/packages/compiler/src/frontend/lowering/builtins/fs-paths.ts b/packages/compiler/src/frontend/lowering/builtins/fs-paths.ts index 38583025d..46a575388 100644 --- a/packages/compiler/src/frontend/lowering/builtins/fs-paths.ts +++ b/packages/compiler/src/frontend/lowering/builtins/fs-paths.ts @@ -5,30 +5,40 @@ * conversion (url.fileURLToPathUrl). The later arguments through the last * one with side effects are evaluated into hidden locals before the * conversion, in source order, so they run even when it throws and each - * reads what it reads in Node. The conversion keeps Node's error order when every - * earlier path is a URL too and each argument Node validates before the - * path is absent or a literal that passes that validation; other URL - * forms fence with SC2020, as do the fs.promises functions, whose - * conversion errors are rejections rather than throws, and existsSync, - * which answers false for a URL it cannot convert. */ + * reads what it reads in Node. Before the conversion, an earlier string + * path gets its null-byte check (copyFileSync, renameSync) and a runtime + * readFileSync encoding its name check, which Node runs first. existsSync + * and the fs.promises functions convert to a value instead + * (url.fileURLToPathValue) and answer false or a rejected promise for a + * conversion error. An argument Node validates before the path must + * otherwise be absent or a literal that passes that validation; other + * forms fence with SC2020. */ import * as ts from "../../ts7/adapter.js"; import { type Lowerer } from "../lowerer.js"; import { locOf } from "../../program.js"; import { sideEffectFreeOptionValue } from "../surfaces.js"; import { stripTypeWrappers } from "../typed-arguments.js"; -import { type IrExpr, type IrStmt, STRING, URL_T } from "../../../ir/ir.js"; +import { boolLit, varRef } from "../../../ir/build.js"; +import { BOOL, DYN, type IrExpr, type IrStmt, STRING, URL_T, VOID } from "../../../ir/ir.js"; +import { InternalCompilerError } from "../../../errors.js"; -/** The fs functions whose path parameters accept a URL: the path - * parameter indexes, and whether Node validates the paths before every - * other argument (otherwise the options come first). */ -const FS_URL_PATHS: Readonly< - Record -> = { +interface FsPathRow { + /** The path parameter indexes. */ + readonly paths: readonly number[]; + /** Whether Node validates the paths before every other argument + * (otherwise the options come first). */ + readonly pathsFirst: boolean; + /** The path parameters' names in Node's errors, when there are two. */ + readonly names?: readonly string[]; +} + +/** The fs functions whose path parameters accept a URL. */ +const FS_URL_PATHS: Readonly> = { accessSync: { paths: [0], pathsFirst: true }, appendFileSync: { paths: [0], pathsFirst: false }, chmodSync: { paths: [0], pathsFirst: true }, chownSync: { paths: [0], pathsFirst: true }, - copyFileSync: { paths: [0, 1], pathsFirst: true }, + copyFileSync: { paths: [0, 1], pathsFirst: true, names: ["src", "dest"] }, lchownSync: { paths: [0], pathsFirst: true }, lstatSync: { paths: [0], pathsFirst: true }, mkdirSync: { paths: [0], pathsFirst: false }, @@ -39,7 +49,7 @@ const FS_URL_PATHS: Readonly< readdirSync: { paths: [0], pathsFirst: false }, realpathSync: { paths: [0], pathsFirst: false }, "realpathSync.native": { paths: [0], pathsFirst: false }, - renameSync: { paths: [0, 1], pathsFirst: true }, + renameSync: { paths: [0, 1], pathsFirst: true, names: ["oldPath", "newPath"] }, rmSync: { paths: [0], pathsFirst: false }, rmdirSync: { paths: [0], pathsFirst: true }, statSync: { paths: [0], pathsFirst: true }, @@ -48,43 +58,66 @@ const FS_URL_PATHS: Readonly< writeFileSync: { paths: [0], pathsFirst: false }, }; -/** The fs.promises functions with path parameters, by path indexes. */ -const FSP_PATHS: Readonly> = { - access: [0], - appendFile: [0], - chmod: [0], - chown: [0], - copyFile: [0, 1], - lchown: [0], - lstat: [0], - mkdir: [0], - mkdtemp: [0], - open: [0], - opendir: [0], - readFile: [0], - readdir: [0], - realpath: [0], - rename: [0, 1], - rm: [0], - rmdir: [0], - stat: [0], - truncate: [0], - unlink: [0], - writeFile: [0], +/** The fs.promises functions with path parameters. */ +const FSP_PATHS: Readonly> = { + access: { paths: [0], pathsFirst: true }, + appendFile: { paths: [0], pathsFirst: false }, + chmod: { paths: [0], pathsFirst: true }, + chown: { paths: [0], pathsFirst: true }, + copyFile: { paths: [0, 1], pathsFirst: true }, + lchown: { paths: [0], pathsFirst: true }, + lstat: { paths: [0], pathsFirst: true }, + mkdir: { paths: [0], pathsFirst: false }, + mkdtemp: { paths: [0], pathsFirst: false }, + open: { paths: [0], pathsFirst: true }, + opendir: { paths: [0], pathsFirst: true }, + readFile: { paths: [0], pathsFirst: false }, + readdir: { paths: [0], pathsFirst: false }, + realpath: { paths: [0], pathsFirst: false }, + rename: { paths: [0, 1], pathsFirst: true }, + rm: { paths: [0], pathsFirst: true }, + rmdir: { paths: [0], pathsFirst: true }, + stat: { paths: [0], pathsFirst: true }, + truncate: { paths: [0], pathsFirst: true }, + unlink: { paths: [0], pathsFirst: true }, + writeFile: { paths: [0], pathsFirst: false }, }; +/** What a path argument of an fs call lowers to (Lowerer.fsPathPlans). */ +export type FsPathPlan = + /** The first URL path: the later arguments with effects, the earlier + * string paths to check, and a runtime encoding to check, all before the + * conversion. */ + | { + kind: "convert"; + staged: ts.Expression[]; + checks: { path: ts.Expression; name: string }[]; + encoding: ts.Expression | null; + } + /** A string path that a later URL path checks: the local that holds it, + * once lowered. */ + | { kind: "save"; local: string | null } + /** A URL path whose conversion error becomes false or a rejection: the + * local that holds the conversion's value. */ + | { kind: "value"; local: string }; + function isUrlArgument(lowerer: Lowerer, node: ts.Expression | undefined): boolean { return node !== undefined && lowerer.mapTypeOf(lowerer.typeOf(node))?.kind === "url"; } +function stripParens(node: ts.Expression): ts.Expression { + let e = node; + while (ts.isParenthesizedExpression(e)) e = e.expression; + return e; +} + /** A literal that Node's option validation accepts before it reads the * path: a string (the checker admits only the declared encodings, flags * and type names), a boolean, an integer in [0, 2^31 - 1] (every numeric * option of these functions accepts that range), undefined or null, or an * object literal of those. */ function preValidatedLiteral(node: ts.Expression): boolean { - let e = node; - while (ts.isParenthesizedExpression(e)) e = e.expression; + const e = stripParens(node); if (ts.isStringLiteralLike(e)) return true; if ( e.kind === ts.SyntaxKind.TrueKeyword || @@ -108,39 +141,59 @@ function preValidatedLiteral(node: ts.Expression): boolean { return false; } -/** SC2020 when the call passes a URL path in a form whose conversion - * order would differ from Node's (see the file comment). */ -function checkUrlPaths( +const HINT = "convert the URL first: fileURLToPath(url) from node:url"; + +/** SC2020 for an argument Node validates before the paths that is neither + * absent nor a literal passing that validation, other than a string + * readFileSync encoding (returned: it is checked before the conversion). + * writeFileSync/appendFileSync's data is checked after the path. */ +function optionsBeforePaths( lowerer: Lowerer, - call: ts.CallExpression, - module: string, + args: readonly ts.Expression[], member: string, -): void { - const args = call.arguments.nodes; - const name = module === "fs/promises" ? `fs.promises.${member}` : member; - const hint = "convert the URL first: fileURLToPath(url) from node:url"; - if (module === "fs/promises") { - if ((FSP_PATHS[member] ?? []).some((i) => isUrlArgument(lowerer, args[i]))) - lowerer.noLowering(`${name} with a URL path`, call, hint); - return; + row: FsPathRow, + name: string, +): ts.Expression | null { + if (row.pathsFirst) return null; + const data = /^(writeFile|appendFile)(Sync)?$/.test(member) ? 1 : -1; + let encoding: ts.Expression | null = null; + for (let i = 0; i < args.length; i++) { + const arg = args[i]!; + if (row.paths.includes(i) || i === data || preValidatedLiteral(arg)) continue; + if ( + member === "readFileSync" && + i === 1 && + lowerer.mapTypeOf(lowerer.typeOf(arg))?.kind === "string" + ) { + encoding = stripTypeWrappers(arg); + continue; + } + lowerer.noLowering(`${name} with a URL path and options that are not literals`, arg, HINT); } - if (member === "existsSync" && isUrlArgument(lowerer, args[0])) - lowerer.noLowering(`${name} with a URL path`, call, hint); - const row = FS_URL_PATHS[member]; - if (!row) return; - const first = row.paths.find((i) => isUrlArgument(lowerer, args[i])); - if (first === undefined) return; - if (args.some(ts.isSpreadElement)) - lowerer.noLowering(`${name} with spread arguments and a URL path`, call); - // The runtime checks a string path after the conversion, so a string - // path Node checks first cannot precede the URL. - if (row.paths.some((i) => i < first && args[i] !== undefined)) - lowerer.noLowering(`${name} with a string path before a URL path`, call, hint); - // Every argument from the URL through the last one with effects is - // evaluated ahead of the conversion, in source order: a later argument's - // effect (an assignment, say) must not change what an earlier one read. + return encoding; +} + +/** The arguments after the URL path that are evaluated ahead of the + * conversion: every one through the last with effects or that `force` + * names, in source order. An object or array literal among them is + * SC2020: its members are lowered one by one, so it cannot be evaluated + * ahead of the conversion as one value. */ +function stagedAfter( + lowerer: Lowerer, + args: readonly ts.Expression[], + first: number, + name: string, + force: (e: ts.Expression, i: number) => boolean, +): ts.Expression[] { + // Every argument from the URL through the last one with effects (or that + // the caller forces) is evaluated ahead of the conversion, in source + // order: a later argument's effect (an assignment, say) must not change + // what an earlier one read. let last = first; - for (let i = first + 1; i < args.length; i++) if (!sideEffectFreeOptionValue(args[i]!)) last = i; + for (let i = first + 1; i < args.length; i++) { + const e = stripTypeWrappers(args[i]!); + if (!sideEffectFreeOptionValue(e) || force(e, i)) last = i; + } const staged: ts.Expression[] = []; for (let i = first + 1; i <= last; i++) { // Keyed without type-only wrappers (`satisfies`, `as`, `!`), so a @@ -154,56 +207,190 @@ function checkUrlPaths( ? `${name} with a URL path and a literal before a later argument that has effects` : `${name} with a URL path and a later literal that has effects`, e, - hint, + HINT, ); } staged.push(e); } - if (staged.length > 0) { - lowerer.stagedAfterPath.set(args[first]!, staged); - for (const e of staged) lowerer.stagedArguments.set(e, null); - } - if (row.pathsFirst) return; - // writeFileSync/appendFileSync's data is checked after the path. - const data = member === "writeFileSync" || member === "appendFileSync" ? 1 : -1; - for (let i = 0; i < args.length; i++) { - if (row.paths.includes(i) || i === data || preValidatedLiteral(args[i]!)) continue; - lowerer.noLowering(`${name} with a URL path and options that are not literals`, args[i]!, hint); - } + return staged; } -/** Fences URL paths that cannot convert in Node's order: the check every - * fs and fs.promises call runs before lowering its arguments. */ +/** Plans the URL paths of a synchronous fs call (see the file comment): + * the check every fs call runs before lowering its arguments. */ export function checkFsUrlPaths( lowerer: Lowerer, call: ts.CallExpression, bi: { module: string; member: string }, ): void { - if (bi.module === "fs" || bi.module === "fs/promises") - checkUrlPaths(lowerer, call, bi.module, bi.member); + if (bi.module !== "fs") return; + const row = FS_URL_PATHS[bi.member]; + if (!row) return; + const args = call.arguments.nodes; + const first = row.paths.find((i) => isUrlArgument(lowerer, args[i])); + if (first === undefined || lowerer.fsPathPlans.has(stripParens(args[first]!))) return; + const name = bi.member; + if (args.some(ts.isSpreadElement)) + lowerer.noLowering(`${name} with spread arguments and a URL path`, call); + const checks: { path: ts.Expression; name: string }[] = []; + for (const i of row.paths) { + if (i >= first || args[i] === undefined) continue; + const path = stripParens(args[i]!); + checks.push({ path, name: row.names?.[i] ?? "path" }); + lowerer.fsPathPlans.set(path, { kind: "save", local: null }); + } + const encoding = optionsBeforePaths(lowerer, args, bi.member, row, name); + const staged = stagedAfter(lowerer, args, first, name, (e) => e === encoding); + for (const e of staged) lowerer.stagedArguments.set(e, null); + lowerer.fsPathPlans.set(stripParens(args[first]!), { kind: "convert", staged, checks, encoding }); +} + +/** existsSync and the fs.promises functions with URL paths: each URL + * converts to a value (url.fileURLToPathValue) after the arguments are + * evaluated, and the call runs on the converted paths only when every + * conversion produced a string; otherwise existsSync answers false and an + * fs.promises function a promise rejected with the first conversion's + * error. `lowerCall` lowers the call itself, whose URL paths then read the + * converted values. Null for every other call. */ +export function lowerFallibleFsUrlCall( + lowerer: Lowerer, + call: ts.CallExpression, + bi: { module: string; member: string }, + lowerCall: () => IrExpr, +): IrExpr | null { + const row = + bi.module === "fs/promises" + ? FSP_PATHS[bi.member] + : bi.module === "fs" && bi.member === "existsSync" + ? ({ paths: [0], pathsFirst: true } satisfies FsPathRow) + : undefined; + if (!row) return null; + const args = call.arguments.nodes; + const urls = row.paths.filter((i) => isUrlArgument(lowerer, args[i])); + if (urls.length === 0 || lowerer.fallibleFsCalls.has(call)) return null; + const name = bi.module === "fs/promises" ? `fs.promises.${bi.member}` : bi.member; + if (args.some(ts.isSpreadElement)) + lowerer.noLowering(`${name} with spread arguments and a URL path`, call); + const first = urls[0]!; + // A string path before the URL would be checked in the call itself, + // after the conversion. + if (row.paths.some((i) => i < first && args[i] !== undefined)) + lowerer.noLowering(`${name} with a string path before a URL path`, call, HINT); + if (optionsBeforePaths(lowerer, args, bi.member, row, name) !== null) + lowerer.noLowering(`${name} with a URL path and options that are not literals`, args[1]!, HINT); + const loc = locOf(call); + const stmts: IrStmt[] = []; + const values = new Map(); + const save = (value: IrExpr, label: string, at: ts.Node): string => { + const slot = lowerer.declareHiddenLocal(label, value.type); + stmts.push({ kind: "varDecl", localId: slot.id, init: value, loc: locOf(at) }); + return slot.id; + }; + values.set(first, save(lowerer.lowerExprExpecting(args[first]!, URL_T), "%fsUrl", args[first]!)); + const staged = stagedAfter(lowerer, args, first, name, (_e, i) => urls.includes(i)); + for (const e of staged) { + // A call lowered again (an array-literal element) evaluates the + // argument anew; the slot an earlier lowering saved it in is gone. + lowerer.stagedArguments.delete(e); + const value = lowerer.lowerExpr(e); + const slot = save(value, "%fsArg", e); + lowerer.stagedArguments.set(e, { localId: slot, type: value.type }); + const index = args.findIndex((arg) => stripTypeWrappers(arg) === e); + if (urls.includes(index)) values.set(index, slot); + } + const results: string[] = []; + for (const i of urls) { + const url = varRef(values.get(i)!, URL_T, loc); + const converted: IrExpr = { + kind: "libCall", + fn: "url.fileURLToPathValue", + args: [url], + type: DYN, + loc, + }; + const local = save(converted, "%fsPathValue", args[i]!); + lowerer.fsPathPlans.set(stripParens(args[i]!), { kind: "value", local }); + results.push(local); + } + lowerer.fallibleFsCalls.add(call); + let inner: IrExpr; + try { + inner = lowerCall(); + } finally { + lowerer.fallibleFsCalls.delete(call); + } + let result = inner; + for (let k = results.length - 1; k >= 0; k--) { + const value = varRef(results[k]!, DYN, loc); + const failed: IrExpr = + bi.module === "fs/promises" + ? { kind: "intrinsic", name: "promise.reject", args: [value], type: inner.type, loc } + : boolLit(false, loc); + result = { + kind: "ternary", + cond: { kind: "dynTest", test: "string", value, type: BOOL, loc }, + then: result, + else_: failed, + type: inner.type, + loc, + }; + } + return { kind: "seqExpr", stmts, result, type: inner.type, loc }; } /** An fs path argument as a string: a URL converts with fileURLToPath's * conversion (url.fileURLToPathUrl), which throws Node's errors for other - * schemes, hosts and encoded separators. */ + * schemes, hosts and encoded separators, after the checks its plan names. */ export function lowerFsPath(lowerer: Lowerer, node: ts.Expression): IrExpr { - if (!isUrlArgument(lowerer, node)) return lowerer.lowerExprExpecting(node, STRING); const loc = locOf(node); + const plan = lowerer.fsPathPlans.get(stripParens(node)); + if (plan?.kind === "value") + return { kind: "dynCheck", value: varRef(plan.local, DYN, loc), type: STRING, loc }; + if (!isUrlArgument(lowerer, node)) { + const value = lowerer.lowerExprExpecting(node, STRING); + if (plan?.kind !== "save") return value; + const slot = lowerer.declareHiddenLocal("%fsPath", STRING); + plan.local = slot.id; + return { + kind: "seqExpr", + stmts: [{ kind: "varDecl", localId: slot.id, init: value, loc }], + result: varRef(slot.id, STRING, loc), + type: STRING, + loc, + }; + } const url = lowerer.lowerExprExpecting(node, URL_T); - const staged = lowerer.stagedAfterPath.get(node); - if (staged === undefined) + if (plan?.kind !== "convert") return { kind: "libCall", fn: "url.fileURLToPathUrl", args: [url], type: STRING, loc }; // The URL and the later arguments with effects, in source order, then - // the conversion. + // the checks Node runs first, then the conversion. const saved = lowerer.declareHiddenLocal("%fsUrl", URL_T); const stmts: IrStmt[] = [{ kind: "varDecl", localId: saved.id, init: url, loc }]; - for (const arg of staged) { + for (const arg of plan.staged) { lowerer.stagedArguments.delete(arg); const value = lowerer.lowerExpr(arg); const slot = lowerer.declareHiddenLocal("%fsArg", value.type); stmts.push({ kind: "varDecl", localId: slot.id, init: value, loc: locOf(arg) }); lowerer.stagedArguments.set(arg, { localId: slot.id, type: value.type }); } + const check = (fn: "fs.checkPath" | "fs.checkReadEncoding", args: IrExpr[]): void => { + stmts.push({ kind: "exprStmt", expr: { kind: "libCall", fn, args, type: VOID, loc }, loc }); + }; + for (const { path, name } of plan.checks) { + const saved = lowerer.fsPathPlans.get(path); + if (saved?.kind !== "save" || saved.local === null) + throw new InternalCompilerError("an fs path checked before it was lowered"); + check("fs.checkPath", [ + varRef(saved.local, STRING, loc), + { kind: "strLit", value: name, type: STRING, loc }, + ]); + } + if (plan.encoding !== null) { + const slot = lowerer.stagedArguments.get(plan.encoding); + if (!slot) throw new InternalCompilerError("an fs encoding checked before it was saved"); + check("fs.checkReadEncoding", [ + lowerer.coerceToExpected(varRef(slot.localId, slot.type, loc), STRING), + ]); + } return { kind: "seqExpr", stmts, @@ -219,7 +406,12 @@ export function lowerFsPath(lowerer: Lowerer, node: ts.Expression): IrExpr { }; } -/** Whether `index` is a path parameter of the fs function `member`. */ -export function isFsPathParam(member: string, index: number): boolean { - return FS_URL_PATHS[member]?.paths.includes(index) === true; +/** Whether `index` is a path parameter of the fs or fs.promises function + * `member`. */ +export function isFsPathParam(module: string, member: string, index: number): boolean { + if (module === "fs/promises") return FSP_PATHS[member]?.paths.includes(index) === true; + if (module !== "fs") return false; + return ( + (member === "existsSync" && index === 0) || FS_URL_PATHS[member]?.paths.includes(index) === true + ); } diff --git a/packages/compiler/src/frontend/lowering/builtins/module-calls.ts b/packages/compiler/src/frontend/lowering/builtins/module-calls.ts index e5446291f..2aaa2f80f 100644 --- a/packages/compiler/src/frontend/lowering/builtins/module-calls.ts +++ b/packages/compiler/src/frontend/lowering/builtins/module-calls.ts @@ -25,7 +25,7 @@ import { lowerFsWriteOptionsCall, lowerFsReadPathCall, } from "./filesystem-calls.js"; -import { checkFsUrlPaths, isFsPathParam, lowerFsPath } from "./fs-paths.js"; +import { checkFsUrlPaths, isFsPathParam, lowerFallibleFsUrlCall, lowerFsPath } from "./fs-paths.js"; import { lowerBufferEncodingCall } from "./text-codecs.js"; import { lowerUtilTypeCall } from "./util-types.js"; import { InternalCompilerError } from "../../../errors.js"; @@ -59,6 +59,10 @@ export function lowerBuiltinModuleCall( loc: SrcLoc, ): IrExpr { const name = ts.getTextOfNode(expr.expression); + const fallible = lowerFallibleFsUrlCall(lowerer, expr, bi, () => + lowerBuiltinModuleCall(lowerer, expr, bi, fn, loc), + ); + if (fallible) return fallible; checkFsUrlPaths(lowerer, expr, bi); if (bi.module === "util/types") { return lowerUtilTypeCall(lowerer, expr, bi, loc, name); @@ -258,7 +262,7 @@ export function lowerBuiltinModuleCall( bi.member === "readFile" && expr.arguments.nodes.length === 1 ) { - const path = lowerer.lowerExprExpecting(expr.arguments.nodes[0]!, STRING); + const path = lowerFsPath(lowerer, expr.arguments.nodes[0]!); return { kind: "libCall", fn: "fsp.readFileBytes", @@ -473,7 +477,7 @@ export function lowerBuiltinModuleCall( args = lowerer.completeArgs(expr.arguments.nodes, shapes, loc, expr); } else { args = expr.arguments.nodes.map((a, i) => - bi.module === "fs" && isFsPathParam(bi.member, i) + isFsPathParam(bi.module, bi.member, i) ? lowerFsPath(lowerer, a) : lowerer.lowerExprExpecting(a, fn.params[i]), ); diff --git a/packages/compiler/src/frontend/lowering/cjs-inline-require.ts b/packages/compiler/src/frontend/lowering/cjs-inline-require.ts index 2b28c6533..10549a030 100644 --- a/packages/compiler/src/frontend/lowering/cjs-inline-require.ts +++ b/packages/compiler/src/frontend/lowering/cjs-inline-require.ts @@ -28,8 +28,10 @@ import { isModuleExportsAccess, locOf, npmStaticDepSf7, + requireBindingEarlyUse7, requireSpecOf, resolveImport, + splitRequireCallOf, } from "../program.js"; import { createRequireCalleeFileOf } from "./builtins/module-bindings.js"; import { isCjsRequireGlobal } from "./lower-node-module.js"; @@ -43,6 +45,332 @@ export interface InlineRequire { dep: ts.SourceFile; } +/** A top-level `var m; m = require("./x")` binding. Node evaluates the + * require at the assignment; the binding is alias plumbing exactly like + * `const m = require("./x")` for every later read. */ +export interface SplitRequireBinding { + decl: ts.VariableDeclaration; + assign: ts.BinaryExpression; + call: ts.CallExpression; + spec: string; + dep: ts.SourceFile; +} + +function symbolOfIdentifierValue(lowerer: Lowerer, ident: ts.Identifier): ts.Symbol | undefined { + const parent = ident.parent; + // A destructuring shorthand target resolves to the property symbol at + // the name, but reads/writes the variable through its value symbol. + if (ts.isShorthandPropertyAssignment(parent) && parent.name === ident) { + return ( + lowerer.checker.getShorthandAssignmentValueSymbol(parent) ?? + lowerer.checker.getSymbolAtLocation(ident) + ); + } + return lowerer.checker.getSymbolAtLocation(ident); +} + +function destructuringContainerOf(node: ts.Node): ts.Node | null { + const parent = node.parent; + if (ts.isShorthandPropertyAssignment(parent) && parent.name === node) return parent; + if (ts.isPropertyAssignment(parent) && parent.initializer === node) return parent; + if (ts.isSpreadElement(parent) && parent.expression === node) return parent; + if (ts.isSpreadAssignment(parent) && parent.expression === node) return parent; + return null; +} + +function writeTargetOf(node: ts.Node): ts.Node | null { + let target = node; + for (;;) { + const parent = target.parent; + if ( + ts.isParenthesizedExpression(parent) || + ts.isArrayLiteralExpression(parent) || + ts.isObjectLiteralExpression(parent) + ) { + target = parent; + continue; + } + const container = destructuringContainerOf(target); + if (container === null) break; + target = container; + } + const parent = target.parent; + if ( + ts.isBinaryExpression(parent) && + parent.left === target && + ts.isAssignmentOperator(parent.operatorToken.kind) + ) + return parent; + if ( + (ts.isPrefixUnaryExpression(parent) || ts.isPostfixUnaryExpression(parent)) && + parent.operand === target && + (parent.operator === ts.SyntaxKind.PlusPlusToken || + parent.operator === ts.SyntaxKind.MinusMinusToken) + ) + return parent; + if ((ts.isForInStatement(parent) || ts.isForOfStatement(parent)) && parent.initializer === target) + return parent; + return null; +} + +/** The split form of a top-level require binding: `var m; m = require("./x")`. + * Exactly one write, at a top-level `m = require("")` statement. + * Null for the ordinary `const m = require("./x")` declaration and for + * every form that needs runtime module selection. */ +export function splitRequireBindingOf( + lowerer: Lowerer, + decl: ts.VariableDeclaration, +): SplitRequireBinding | null { + // Cheap shape gate before the cache: ordinary declarations never enter the + // per-Lowerer map. + if (decl.initializer !== undefined || !ts.isIdentifier(decl.name)) return null; + const list = decl.parent as ts.VariableDeclarationList; + if ((list.flags & ts.NodeFlags.Const) !== 0) return null; + const stmt = list.parent; + if (!ts.isVariableStatement(stmt) || !ts.isSourceFile(stmt.parent)) return null; + const cached = lowerer.cjsSplitRequireBindings.get(decl); + if (cached !== undefined) return cached; + const result = computeSplitRequireBinding(lowerer, decl); + lowerer.cjsSplitRequireBindings.set(decl, result); + return result; +} + +function computeSplitRequireBinding( + lowerer: Lowerer, + decl: ts.VariableDeclaration, +): SplitRequireBinding | null { + const sf = ts.getSourceFileOfNode(decl); + if (!isCjsJsFile(sf, lowerer.program)) return null; + if (!sf.text.includes("require")) return null; + const symbol = lowerer.checker.getSymbolAtLocation(decl.name); + if (symbol === undefined) return null; + // Merged declarations make the binding's initialization order ambiguous; + // keep ordinary storage instead of guessing. + let declarations = 0; + for (const other of symbol.declarations) { + if (!ts.isVariableDeclaration(other) || ++declarations > 1) return null; + } + if (declarations !== 1) return null; + + // Find the one top-level `m = ...` statement first: most uninitialized + // variables never reach that shape, so they avoid the full-file write scan. + let assign: ts.BinaryExpression | null = null; + for (const stmt of sf.statements.nodes) { + if (!ts.isExpressionStatement(stmt)) continue; + const expr = stmt.expression; + if ( + !ts.isBinaryExpression(expr) || + expr.operatorToken.kind !== ts.SyntaxKind.EqualsToken || + !ts.isIdentifier(expr.left) || + expr.left.text !== decl.name.text || + lowerer.checker.getSymbolAtLocation(expr.left) !== symbol + ) + continue; + if (assign !== null) return null; + assign = expr; + } + if (assign === null) return null; + + const req = inlineProgramRequireOf(lowerer, assign.right); + if (req === null) return null; + // Preflight treats the same bindings as require declarations (module edge, + // cycle admission, early-read fence); a binding it does not know keeps + // ordinary storage. + if (splitRequireCallOf(lowerer.program, decl) !== req.call) return null; + + // Any other write makes the value depend on runtime control flow. + let writes = 0; + ts.walkPreorder(sf, (node) => { + if (!ts.isIdentifier(node) || node.text !== decl.name.text) return; + if (symbolOfIdentifierValue(lowerer, node) !== symbol) return; + if (writeTargetOf(node) === null) return; + if (++writes > 1) return "stop"; + }); + if (writes !== 1) return null; + + return { decl, assign, call: req.call, spec: req.spec, dep: req.dep }; +} + +/** The split binding an identifier names, or null. */ +export function splitRequireBindingOfIdent( + lowerer: Lowerer, + ident: ts.Identifier, +): SplitRequireBinding | null { + const symbol = symbolOfIdentifierValue(lowerer, ident); + return symbol === undefined ? null : splitBindingOfSymbol(lowerer, symbol); +} + +/** The exact top-level assignment statement that initializes `expr`, or null. */ +export function splitRequireAssignmentOf( + lowerer: Lowerer, + expr: ts.Expression, +): SplitRequireBinding | null { + if ( + !ts.isBinaryExpression(expr) || + expr.operatorToken.kind !== ts.SyntaxKind.EqualsToken || + !ts.isIdentifier(expr.left) + ) + return null; + const bindingOfIdent = splitRequireBindingOfIdent(lowerer, expr.left); + return bindingOfIdent !== null && bindingOfIdent.assign === expr ? bindingOfIdent : null; +} + +/** The whole-export symbol a module's `module.exports = ` names, + * or null when the module is a table. */ +export function wholeExportSymbolOfModule(lowerer: Lowerer, dep: ts.SourceFile): ts.Symbol | null { + const cached = lowerer.cjsWholeExportSymbols.get(dep); + if (cached !== undefined) return cached; + if (cjsNamespaceModule(lowerer, dep)) { + lowerer.cjsWholeExportSymbols.set(dep, null); + return null; + } + const moduleSymbol = lowerer.checker.getSymbolAtLocation(dep); + let symbol = moduleSymbol?.getExports()?.get("export=" as ts.__String); + if (symbol === undefined) { + lowerer.cjsWholeExportSymbols.set(dep, null); + return null; + } + if (symbol.flags & ts.SymbolFlags.Alias) symbol = lowerer.checker.getAliasedSymbol(symbol); + lowerer.cjsWholeExportSymbols.set(dep, symbol); + return symbol; +} + +function splitBindingOfSymbol(lowerer: Lowerer, symbol: ts.Symbol): SplitRequireBinding | null { + const decl = symbol.declarations.find(ts.isVariableDeclaration); + return decl === undefined ? null : splitRequireBindingOf(lowerer, decl); +} + +/** The target whole-export symbol behind a split-binding symbol. */ +function splitWholeExportSymbolOfSymbol(lowerer: Lowerer, symbol: ts.Symbol): ts.Symbol | null { + const binding = splitBindingOfSymbol(lowerer, symbol); + return binding === null ? null : wholeExportSymbolOfModule(lowerer, binding.dep); +} + +/** True when a CommonJS module has a live member export (`exports.x` or + * `module.exports.x`) after all `module.exports =` replacements. Those + * members need a mutable whole-export root. */ +export function cjsHasLiveMemberExports(lowerer: Lowerer, sf: ts.SourceFile): boolean { + const cached = lowerer.cjsLiveMemberExports.get(sf); + if (cached !== undefined) return cached; + const stmts = sf.statements.nodes; + let lastTable = -1; + for (let i = 0; i < stmts.length; i++) { + if (cjsExportAssignmentOf(stmts[i]!)?.kind === "table") lastTable = i; + } + let live = false; + // Only members attached after the last replacement survive in Node. + if (lastTable >= 0) { + for (let i = lastTable + 1; i < stmts.length; i++) { + const stmt = stmts[i]!; + if (cjsExportAssignmentOf(stmt)?.kind === "member" && cjsExportDiscardReason(stmt) === null) { + live = true; + break; + } + } + } + lowerer.cjsLiveMemberExports.set(sf, live); + return live; +} + +/** The wrapper's export= symbol when a split binding is re-exported whole + * (`module.exports = m`) and that assignment owns storage for later member + * writes. Importers must read the wrapper's storage, not the split + * binding's underlying value. */ +function splitWholeExportStorageSymbolOf(lowerer: Lowerer, symbol: ts.Symbol): ts.Symbol | null { + const binding = splitBindingOfSymbol(lowerer, symbol); + if (binding === null) return null; + if (wholeExportSymbolOfModule(lowerer, binding.dep) === null) return null; + const sf = ts.getSourceFileOfNode(binding.decl); + if (!cjsHasLiveMemberExports(lowerer, sf)) return null; + const whole = cjsWholeExportValueOf(sf); + if (whole === null) return null; + let rhs: ts.Expression = whole.rhs; + while (ts.isParenthesizedExpression(rhs)) rhs = rhs.expression; + if (!ts.isIdentifier(rhs) || lowerer.checker.getSymbolAtLocation(rhs) !== symbol) return null; + const moduleSymbol = lowerer.checker.getSymbolAtLocation(sf); + let exportSymbol = moduleSymbol?.getExports()?.get("export=" as ts.__String); + if (exportSymbol === undefined) return null; + if (exportSymbol.flags & ts.SymbolFlags.Alias) + exportSymbol = lowerer.checker.getAliasedSymbol(exportSymbol); + return exportSymbol; +} + +/** The source file whose `module.exports =` assignment declares `symbol`. */ +function moduleExportSourceFileOf(symbol: ts.Symbol): ts.SourceFile | null { + for (const decl of symbol.declarations) { + if ( + ts.isBinaryExpression(decl) && + isModuleExportsAccess(decl.left) && + ts.isExpressionStatement(decl.parent) && + ts.isSourceFile(decl.parent.parent) + ) + return decl.getSourceFile(); + } + return null; +} + +/** One hop from a wrapper's export= symbol to the value it re-exports + * (`module.exports = require(...)` or `= `), or null. A + * wrapper with live members owns storage for them, so it is not followed. */ +function wholeReexportTargetOf(lowerer: Lowerer, symbol: ts.Symbol): ts.Symbol | null { + const sf = moduleExportSourceFileOf(symbol); + if (sf === null) return null; + // A wrapper with live members owns storage for them; importers must keep + // reading that root rather than the inner value. + if (cjsHasLiveMemberExports(lowerer, sf)) return null; + const whole = cjsWholeExportValueOf(sf); + if (whole === null) return null; + const inner = inlineProgramRequireOf(lowerer, whole.rhs); + if (inner !== null) return wholeExportSymbolOfModule(lowerer, inner.dep); + let rhs: ts.Expression = whole.rhs; + while (ts.isParenthesizedExpression(rhs)) rhs = rhs.expression; + if (!ts.isIdentifier(rhs)) return null; + const rhsSymbol = lowerer.checker.getSymbolAtLocation(rhs); + return rhsSymbol === undefined ? null : splitWholeExportSymbolOfSymbol(lowerer, rhsSymbol); +} + +/** Follow split bindings and whole re-exports to the ultimate value symbol. */ +function followSplitWholeTarget(lowerer: Lowerer, candidate: ts.Symbol | null): ts.Symbol | null { + if (candidate === null) return null; + let symbol = candidate; + const seen = new Set(); + for (let depth = 0; depth < 32 && !seen.has(symbol); depth++) { + seen.add(symbol); + const next = + splitWholeExportSymbolOfSymbol(lowerer, symbol) ?? wholeReexportTargetOf(lowerer, symbol); + if (next === null) break; + symbol = next; + } + return symbol; +} + +/** The target whole-export symbol behind `module.exports = `, + * letting importers of that wrapper resolve to the real value symbol. */ +export function splitWholeExportAliasTargetOf( + lowerer: Lowerer, + symbol: ts.Symbol, +): ts.Symbol | null { + const storage = splitWholeExportStorageSymbolOf(lowerer, symbol); + if (storage !== null) return followSplitWholeTarget(lowerer, storage); + const direct = followSplitWholeTarget(lowerer, splitWholeExportSymbolOfSymbol(lowerer, symbol)); + if (direct !== null) return direct; + return followSplitWholeTarget(lowerer, wholeReexportTargetOf(lowerer, symbol)); +} + +/** The first read of a split binding that code before its assignment can + * reach, using the same reachability model as ordinary require bindings. */ +export function splitRequireEarlyReadOf( + lowerer: Lowerer, + binding: SplitRequireBinding, +): ts.Identifier | null { + const sf = ts.getSourceFileOfNode(binding.decl); + const stmt = binding.assign.parent; + // `binding` was recognized only from a top-level `m = require(...)` + // statement, so the statement index is always present. + const index = sf.statements.nodes.indexOf(stmt as ts.ExpressionStatement); + return requireBindingEarlyUse7(lowerer.program, sf, index, binding.decl, []); +} + /** A `require("")` call of the CommonJS global in a CommonJS JS * file whose target is a compiled program module (relative, aliased, or an * opted-in --npm-static package). Builtins, JSON documents and @@ -108,13 +436,6 @@ export function inlineNamespaceRequireOf( /** `value` evaluated after the required module's run-once %init (and its * module-registry link) at the require's own position. */ export function withRequireInit(lowerer: Lowerer, req: InlineRequire, value: IrExpr): IrExpr { - if (lowerer.inlineRequireCycleCalls.has(req.call)) { - lowerer.unsupported( - "SC1090", - req.call, - `require() of '${req.spec}' while it is still evaluating (a require cycle: Node answers its partial exports, which the static export table does not model)`, - ); - } // Every inline program require is a preflight module edge, so its module // has an initializer; never read its exports without evaluating it. if (!lowerer.initNameOf.has(req.dep)) { diff --git a/packages/compiler/src/frontend/lowering/class-dynamic-dispatch.ts b/packages/compiler/src/frontend/lowering/class-dynamic-dispatch.ts index abf03811e..f219fd5e5 100644 --- a/packages/compiler/src/frontend/lowering/class-dynamic-dispatch.ts +++ b/packages/compiler/src/frontend/lowering/class-dynamic-dispatch.ts @@ -717,6 +717,105 @@ export function classForInHasKey( return { kind: "call", callee: name, args: [value, key], type: BOOL, loc }; } +/** Box class instances at their exact class. `%dyn.class.normalize` turns a + * capsule of a class with subclasses into a capsule of the instance's own + * class before any member table reads it, so every such box was followed + * by a second capsule. Each conversion of a value whose static class has a + * normalization branch now selects the exact class at the conversion, with + * the same tests in the same order (%dyn.class.boxExact:C), and the + * normalization of the resulting capsule falls through. Only JavaScript + * class hierarchies, whose instances live in untyped code, take the exact + * box. */ +export function boxClassInstancesExactly(lowerer: Lowerer, functions: IrFunction[]): void { + const normalize = lowerer.liftedFnNamed("%dyn.class.normalize"); + if (!normalize) return; + // Static class → its constructible descendants in normalization order. + const branches = new Map(); + for (const stmt of normalize.body) { + if (stmt.kind !== "if" || stmt.cond.kind !== "libCall" || stmt.cond.fn !== "dyn.typedRefIs") + continue; + const key = stmt.cond.args[1]; + if (key?.kind !== "strLit" || !key.value.startsWith("object:")) continue; + const children: string[] = []; + for (const inner of stmt.then) { + if (inner.kind !== "if" || inner.cond.kind !== "instanceOf") continue; + children.push(inner.cond.className); + } + // TypeScript hierarchies keep their static-class capsules: their boxes + // are rarer, and an exact box would emit each subclass's checked view. + const className = key.value.slice("object:".length); + const decl = lowerer.classes.get(className)?.decl; + if (!decl || !isJsSourceFile(ts.getSourceFileOfNode(decl))) continue; + if (children.length) branches.set(className, children); + } + if (branches.size === 0) return; + const loc = normalize.loc; + const helpers = new Map(); + const helperFor = (className: string): string => { + const known = helpers.get(className); + if (known !== undefined) return known; + const name = `%dyn.class.boxExact:${className}`; + helpers.set(className, name); + const type: IrType = { kind: "object", className }; + const value = varRef("value", type, loc); + functions.push({ + name, + params: [{ localId: "value", name: "value", type }], + returnType: DYN, + locals: [{ id: "value", name: "value", type, mutable: false }], + body: [ + ...branches.get(className)!.map((child): IrStmt => ({ + kind: "if", + cond: { kind: "instanceOf", value, className: child, type: BOOL, loc }, + then: [ + { + kind: "return", + value: { + kind: "dynFrom", + value: { + kind: "downcast", + value, + type: { kind: "object", className: child }, + loc, + }, + type: DYN, + loc, + }, + loc, + }, + ], + else_: null, + loc, + })), + { kind: "return", value: { kind: "dynFrom", value, type: DYN, loc }, loc }, + ], + loc, + }); + return name; + }; + const rewrite = (fn: IrFunction): void => { + fn.body = transformStmtList(fn.body, { + stmt: (statement) => statement, + expr: (expression) => + expression.kind === "dynFrom" && + expression.value.type.kind === "object" && + branches.has(expression.value.type.className) + ? { + kind: "call", + callee: helperFor(expression.value.type.className), + args: [expression.value], + type: DYN, + loc: expression.loc, + } + : expression, + }); + }; + for (const fn of [...functions]) { + if (fn === normalize || fn.name.startsWith("%dyn.class.boxExact:")) continue; + rewrite(fn); + } +} + /** Record field creation after the dispatch worklist closes, including writes * in generated member tables. Native values stay in their slots; the bag * owns only their property presence, attributes, and insertion position. */ @@ -1634,6 +1733,15 @@ export class ClassDynamicDispatch { if (this.deletedNames === undefined) this.deletedNames = deletedPropertyNames(lowerer.moduleOrder); if (!root.base?.def.runtime && !fixedFieldFamily(root, this.deletedNames)) track(root); + // An Error family's bag records where `name` and `message` were + // created, which the error slots do not. + if (root.base?.def.name === "%Error") { + const order = (current: ClassInfo): void => { + current.def.errorBagOrder = true; + current.subclasses.forEach(order); + }; + order(info); + } } const loc = this.propertyBag.loc; const { receiver, condition } = this.propertyReceiver(plan, loc); diff --git a/packages/compiler/src/frontend/lowering/class-method-mutations.ts b/packages/compiler/src/frontend/lowering/class-method-mutations.ts index a07a4d3e1..22d2a722a 100644 --- a/packages/compiler/src/frontend/lowering/class-method-mutations.ts +++ b/packages/compiler/src/frontend/lowering/class-method-mutations.ts @@ -46,6 +46,13 @@ export function collectClassMethodMutations( const typedClasses: (ts.ClassDeclaration | ts.ClassExpression)[] = []; const symbolMethods = new Set(); let unknownKey: ts.Node | undefined; + /** Every write with an unknown key: each may install a replacement of any + * method name, and the key-order witness asks what each one installs. */ + const unknownKeySites: ts.Node[] = []; + const markUnknownKey = (site: ts.Node): void => { + unknownKey = site; + unknownKeySites.push(site); + }; let numericKey: ts.Node | undefined; let unknownOwnField = false; // `sym:iterator` for `Symbol.iterator`: the name a class method declared @@ -83,7 +90,7 @@ export function collectClassMethodMutations( for (const key of computedMethods) for (const name of literalValues(lowerer.typeOf(key)) ?? []) methods.add(String(name)); const markName = (name: string, site: ts.Node, arrow = false): void => { - if (name === "prototype" || name === "__proto__") unknownKey = site; + if (name === "prototype" || name === "__proto__") markUnknownKey(site); if (methods.has(name)) lowerer.noteMethodAccess(name, site); if (!arrow) receiverFields.add(name); }; @@ -170,14 +177,32 @@ export function collectClassMethodMutations( // A string index whose values cannot be functions excludes callable // method slots. Class instances have no implicit index signature, so such // a dictionary is only a class view when the class declares that index - // signature, and then every method must be assignable to its value type. - const functionFreeDictionary = (value: ts.Expression): boolean => - lowerer.checker - .getIndexInfosOfType(lowerer.typeOf(value)) + // signature, and then every method must be assignable to its value type, + // or when the dictionary keeps checked identity: it then holds the + // existing objects it receives, class instances included. + // A string-keyed dictionary that keeps checked identity holds the + // existing objects it receives, class instances included, so any write + // through it can replace a method. + const dictionaryView = (value: ts.Expression): boolean => { + const type = lowerer.typeOf(value); + return ( + lowerer.checker.getPropertiesOfType(type).length === 0 && + lowerer.checker + .getIndexInfosOfType(type) + .some((index) => (index.keyType.flags & ts.TypeFlags.StringLike) !== 0) && + lowerer.classImplementedProtocol(type) + ); + }; + const functionFreeDictionary = (value: ts.Expression): boolean => { + const type = lowerer.typeOf(value); + if (lowerer.classImplementedProtocol(type)) return false; + return lowerer.checker + .getIndexInfosOfType(type) .some( (index) => (index.keyType.flags & ts.TypeFlags.StringLike) !== 0 && functionFree(index.type), ); + }; const literalLoopKeys = (key: ts.Expression): (string | number)[] | null => { if (!ts.isIdentifier(key)) return null; const symbol = lowerer.checker.getSymbolAtLocation(key); @@ -449,11 +474,12 @@ export function collectClassMethodMutations( (lowerer.isStdlibGlobal(node, "Object") || lowerer.isStdlibGlobal(node, "Reflect")) && (!ts.isPropertyAccessExpression(node.parent) || node.parent.expression !== node) ) - unknownKey = node; + markUnknownKey(node); for (const node of reflection) { const objectMethod = lowerer.stdlibGlobalMember(node, "Object"); const reflectMethod = lowerer.stdlibGlobalMember(node, "Reflect"); - if (objectMethod === "setPrototypeOf" || reflectMethod === "setPrototypeOf") unknownKey = node; + if (objectMethod === "setPrototypeOf" || reflectMethod === "setPrototypeOf") + markUnknownKey(node); const single = objectMethod === "defineProperty" || reflectMethod === "defineProperty" || @@ -463,7 +489,7 @@ export function collectClassMethodMutations( if (!single && !multiple) continue; const call = node.parent; if (!ts.isCallExpression(call) || call.expression !== node) { - unknownKey = node; + markUnknownKey(node); continue; } const receiver = call.arguments.nodes[0]; @@ -577,7 +603,10 @@ export function collectClassMethodMutations( ); for (const { target, site } of propertyWrites) { const name = target.name.text; - if (functionFree(lowerer.typeOf(target)) || !methodOwnerCanInhabit(target.expression, name)) + if ( + !dictionaryView(target.expression) && + (functionFree(lowerer.typeOf(target)) || !methodOwnerCanInhabit(target.expression, name)) + ) continue; if (lowerer.prototypeMethodAccesses.has(name)) lowerer.noteMethodSite(name, site); else lowerer.noteMethodAccess(name, site); @@ -618,7 +647,7 @@ export function collectClassMethodMutations( // Numeric writes can replace numeric names but not ordinary names. numericKey = site; } else if (!(flags & ts.TypeFlags.ESSymbolLike)) { - unknownKey = site; + markUnknownKey(site); } } if (numericKey) { @@ -627,7 +656,10 @@ export function collectClassMethodMutations( } } if (unknownKey) { - for (const method of methods) lowerer.noteMethodAccess(method, unknownKey); + for (const method of methods) { + lowerer.prototypeMethodAccesses.set(method, unknownKey); + for (const site of unknownKeySites) lowerer.noteMethodSite(method, site); + } for (const method of symbolMethods) lowerer.replacedSymbolMethods.add(method); } if (!unknownKey && !unknownOwnField) diff --git a/packages/compiler/src/frontend/lowering/class-protocols.ts b/packages/compiler/src/frontend/lowering/class-protocols.ts index 76091b13e..00eedb6c0 100644 --- a/packages/compiler/src/frontend/lowering/class-protocols.ts +++ b/packages/compiler/src/frontend/lowering/class-protocols.ts @@ -10,6 +10,9 @@ export class ClassProtocols { private readonly accepted = new Map(); /** What markIdentityFlows learned about the program, while it runs. */ private facts: FlowFacts | null = null; + /** The value types of the string-keyed dictionaries that keep checked + * identity (see markDictionaryViews). */ + private readonly dictionaryViews = new Set(); constructor( private readonly checker: ts.TypeChecker, @@ -323,6 +326,7 @@ export class ClassProtocols { else if (names !== "all") names.add(name); } } + this.markDictionaryViews(sites, sourceNodes, observedNodes, writeNodes); for (let i = 0; i < looseArguments.length; i++) { const type = typeOf(looseNodes[i]!); if (type === undefined) continue; @@ -697,6 +701,163 @@ export class ClassProtocols { return source !== undefined && this.isProgramClassInstance(source); } + /** String-keyed dictionaries (`Record`, `{ [key: string]: V }`) + * that receive an existing record or class instance. Natively a + * dictionary is a key/value record, and converting another object into + * one copies its fields, so writes through the dictionary and identity + * checks would miss the original. When the program writes through, or + * observes, a value of such a dictionary type, every dictionary with that + * value type keeps checked identity instead (records with the same value + * type share one native layout, so values pass between them). A source + * counts when it is an existing object (a binding, member, element or + * `this`, not a fresh literal or call result) whose type is a program + * class instance or a record with declared properties, or a constant + * `{}`, `object` or `unknown` binding initialized with one. */ + private markDictionaryViews( + sites: readonly { + source: ts.Expression; + target: () => ts.Type | undefined; + contextual?: ts.Expression; + }[], + sourceNodes: readonly ts.Expression[], + observedNodes: readonly ts.Expression[], + writeNodes: readonly ts.Expression[], + ): void { + // The calls the sites' arguments belong to, by callee name, built on + // first use. + let calls: Map | null = null; + const callsNamed = (name: string): readonly (ts.CallExpression | ts.NewExpression)[] => { + if (calls === null) { + calls = new Map(); + for (const site of sites) { + const call = site.contextual?.parent; + if (call === undefined || (!ts.isCallExpression(call) && !ts.isNewExpression(call))) + continue; + const callee = call.expression; + const named = ts.isIdentifier(callee) + ? callee.text + : ts.isPropertyAccessExpression(callee) + ? callee.name.text + : undefined; + if (named === undefined) continue; + const list = calls.get(named) ?? []; + if (!list.includes(call)) list.push(call); + calls.set(named, list); + } + } + return calls.get(name) ?? []; + }; + const candidates: { index: number; sourceType: ts.Type }[] = []; + for (let i = 0; i < sites.length; i++) { + const source = sourceNodes[i]!; + if (!isExistingObject(source)) continue; + const sourceType = attempt(() => this.checker.getTypeAtLocation(source)); + if (sourceType !== undefined && this.dictionarySource(source, sourceType, callsNamed)) + candidates.push({ index: i, sourceType }); + } + if (candidates.length === 0) return; + // One batch for the contextual targets of the candidate sites. + attempt(() => + this.checker.prefetchContextualTypes( + candidates.flatMap(({ index }) => { + const contextual = sites[index]!.contextual; + return contextual === undefined ? [] : [contextual]; + }), + ), + ); + const received = new Set(); + for (const { index, sourceType } of candidates) { + const target = attempt(sites[index]!.target); + const parts = + target === undefined ? [] : target.isUnionType() ? ts.constituentTypes(target) : [target]; + for (const part of parts) { + const value = this.dictionaryValueType(part); + // A dictionary of `unknown` or `any` values is checked-dynamic already. + if ( + value !== undefined && + (value.flags & (ts.TypeFlags.Unknown | ts.TypeFlags.Any)) === 0 && + this.dictionaryValueType(sourceType) !== value + ) + received.add(value); + } + } + if (received.size === 0) return; + // The dictionary values the program writes through or observes. + const seen = new Set(); + for (const node of [...writeNodes, ...observedNodes]) { + const type = attempt(() => this.checker.getTypeAtLocation(node)); + const parts = + type === undefined ? [] : type.isUnionType() ? ts.constituentTypes(type) : [type]; + for (const part of parts) { + const value = this.dictionaryValueType(part); + if (value !== undefined) seen.add(value); + } + } + for (const value of received) if (seen.has(value)) this.dictionaryViews.add(value); + } + + /** Whether `source` holds an existing object that a dictionary + * conversion would copy. */ + private dictionarySource( + source: ts.Expression, + type: ts.Type, + callsNamed: (name: string) => readonly (ts.CallExpression | ts.NewExpression)[], + ): boolean { + if (this.isProgramClassInstance(type) || this.isRecordWithFields(type)) return true; + if (!isDynamicView(this.checker, type) || !ts.isIdentifier(source)) return false; + const decl = attempt(() => this.checker.getSymbolAtLocation(source))?.valueDeclaration; + if (decl === undefined) return false; + const holdsObject = (expr: ts.Expression): boolean => { + const held = attempt(() => this.checker.getTypeAtLocation(this.flowSourceNode(expr))); + return ( + held !== undefined && (this.isProgramClassInstance(held) || this.isRecordWithFields(held)) + ); + }; + if (ts.isParameter(decl)) { + // A parameter holds what its callers pass: the calls of the function + // by name whose signature resolves to it. + const fn = decl.parent; + if (fn === undefined || !ts.isFunctionLike(fn)) return false; + const index = fn.parameters.nodes.indexOf(decl); + const name = functionName(fn); + if (name === undefined || index < 0) return false; + return callsNamed(name).some((call) => { + const argument = call.arguments?.nodes[index]; + return ( + argument !== undefined && + !ts.isSpreadElement(argument) && + attempt(() => this.checker.getResolvedSignature(call)?.declaration) === fn && + holdsObject(argument) + ); + }); + } + return ( + ts.isVariableDeclaration(decl) && + decl.initializer !== undefined && + ts.isVariableDeclarationList(decl.parent) && + (decl.parent.flags & ts.NodeFlags.Const) !== 0 && + holdsObject(decl.initializer) + ); + } + + /** A program object type with declared properties that is not a class + * instance, array, tuple, function or library type. */ + private isRecordWithFields(type: ts.Type): boolean { + return this.isStructuralTarget(type) && this.checker.getPropertiesOfType(type).length > 0; + } + + /** The value type of a string-keyed dictionary with no declared + * properties, or undefined for any other type. */ + private dictionaryValueType(type: ts.Type): ts.Type | undefined { + if ((type.flags & ts.TypeFlags.Object) === 0) return undefined; + if (this.checker.isArrayType(type) || this.checker.isTupleType(type)) return undefined; + if (this.checker.getCallSignatures(type).length > 0) return undefined; + if (this.checker.getPropertiesOfType(type).length > 0) return undefined; + return this.checker + .getIndexInfosOfType(type) + .find((index) => (index.keyType.flags & ts.TypeFlags.String) !== 0)?.type; + } + private isProgramClassInstance(type: ts.Type): boolean { const symbol = type.getSymbol(); return ( @@ -822,7 +983,13 @@ export class ClassProtocols { if ((type.flags & ts.TypeFlags.Object) === 0) return false; const previous = this.answers.get(type); if (previous !== undefined) return previous; - const answer = this.protocol(type); + // A dictionary keeps checked identity when the protocols already mark + // it (a literal whose methods read `this`) or when it receives existing + // objects (markDictionaryViews). + const dictionaryValue = this.dictionaryValueType(type); + const answer = + this.protocol(type) || + (dictionaryValue !== undefined && this.dictionaryViews.has(dictionaryValue)); this.answers.set(type, answer); return answer; } @@ -922,6 +1089,44 @@ const IDENTITY_METHODS = new Set([ "includes", ]); +/** An expression that denotes an object that already exists, not a fresh + * literal or call result. */ +function isExistingObject(node: ts.Expression): boolean { + return ( + ts.isIdentifier(node) || + ts.isPropertyAccessExpression(node) || + ts.isElementAccessExpression(node) || + node.kind === ts.SyntaxKind.ThisKeyword + ); +} + +/** `{}`, `object` and `unknown`: types whose values are checked-dynamic + * and keep the original object. */ +function isDynamicView(checker: ts.TypeChecker, type: ts.Type): boolean { + if (type.flags & (ts.TypeFlags.Unknown | ts.TypeFlags.NonPrimitive)) return true; + return ( + (type.flags & ts.TypeFlags.Object) !== 0 && + checker.getPropertiesOfType(type).length === 0 && + checker.getIndexInfosOfType(type).length === 0 && + checker.getCallSignatures(type).length === 0 && + checker.getConstructSignatures(type).length === 0 + ); +} + +/** The name calls use for a function, method or function-valued binding. */ +function functionName(fn: ts.Node): string | undefined { + if ((ts.isFunctionDeclaration(fn) || ts.isMethodDeclaration(fn)) && fn.name !== undefined) + return ts.isIdentifier(fn.name) ? fn.name.text : undefined; + if ( + (ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) && + fn.parent !== undefined && + ts.isVariableDeclaration(fn.parent) && + ts.isIdentifier(fn.parent.name) + ) + return fn.parent.name.text; + return undefined; +} + function isNullishLiteral(node: ts.Expression): boolean { while (ts.isParenthesizedExpression(node)) node = node.expression; return ( diff --git a/packages/compiler/src/frontend/lowering/containers/array-construction.ts b/packages/compiler/src/frontend/lowering/containers/array-construction.ts index 1f10640c0..1ca51f526 100644 --- a/packages/compiler/src/frontend/lowering/containers/array-construction.ts +++ b/packages/compiler/src/frontend/lowering/containers/array-construction.ts @@ -1,4 +1,5 @@ import { keyedHelperName } from "../stable-names.js"; +import { indexedUnionArms, lowerIndexedUnionToArray } from "../indexed-unions.js"; import { generatorDrain } from "../iterator-adapters.js"; import { identityPreservingWidening } from "../coercions/identity.js"; import { liftedFreshSpread } from "../coercions/fresh-spread.js"; @@ -1054,6 +1055,10 @@ export function lowerArrayFromCall( loc, }; } + // A union of typed arrays and number arrays (indexed-unions.ts). + const indexedArms = indexedUnionArms(lowerer, src.type); + if (indexedArms && args.length === 1) + return lowerIndexedUnionToArray(lowerer, src, indexedArms, loc, true); if (src.type.kind === "set" && args.length === 1) { return { kind: "setIntrinsic", diff --git a/packages/compiler/src/frontend/lowering/containers/bytes.ts b/packages/compiler/src/frontend/lowering/containers/bytes.ts index e56d9fc54..a8890c431 100644 --- a/packages/compiler/src/frontend/lowering/containers/bytes.ts +++ b/packages/compiler/src/frontend/lowering/containers/bytes.ts @@ -1,7 +1,9 @@ import { keyedHelperName } from "../stable-names.js"; +import { allBytesArms, indexedUnionArms, lowerIndexedUnionMethod } from "../indexed-unions.js"; import { boolLit, dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../../ir/build.js"; import { BUF_NUM_METHODS } from "./buffer-numeric-methods.js"; import * as ts from "../../ts7/adapter.js"; +import { constituentTypes } from "../../ts7/checker.js"; import { BIGINT_T, BOOL, @@ -42,7 +44,7 @@ import { lowerStaticallyUndefinedArgument, } from "../optional-arguments.js"; import { lowerArraySpreadItems, lowerCheckedArrayFrom } from "./array-construction.js"; -import { lowerToNumberArgument } from "../lower-exprs.js"; +import { lowerOptionalNumber, lowerToNumberArgument } from "../lower-exprs.js"; import { lowerBytesIteratorValue } from "../iterator-adapters.js"; import { lowerArrayCallback } from "./callback-arguments.js"; import { callbackSite, findPredicateOk, predicateToBoolean } from "./array-callbacks.js"; @@ -1032,6 +1034,119 @@ export function lowerBytesPrototypeSetCall( * variable-width read/writeUIntLE quartet — BUF_NUM_METHODS). Everything * else the lib declares (fill, indexOf, reverse, ...) falls through to * the SC2020 member fence. Null when this isn't a bytes method call. */ +/** The [needle, fromIndex] arguments of TypedArray indexOf, lastIndexOf + * and includes. A present fromIndex converts even when it is undefined + * (NaN, which ToIntegerOrInfinity makes 0); an absent one is 0, or + * +Infinity for lastIndexOf, which starts at the last element. */ +function elementSearchArgs(lowerer: Lowerer, call: ts.CallExpression, name: string): IrExpr[] { + const nodes = call.arguments.nodes; + const loc = locOf(call); + const needle = lowerer.lowerExprExpecting(nodes[0]!, F64); + const from: IrExpr = nodes[1] + ? lowerOptionalNumber(lowerer, lowerer.lowerExpr(nodes[1]), locOf(nodes[1]), nodes[1]) + : ({ + kind: "numLit", + value: name === "lastIndexOf" ? Infinity : 0, + type: F64, + loc, + } satisfies IrExpr); + // An undefined fromIndex is NaN once converted, which starts at 0. + if (from.kind === "unitLit") return [needle, { kind: "numLit", value: NaN, type: F64, loc }]; + if (from.type.kind === "undefinedT" || from.type.kind === "void") + return [ + needle, + { + kind: "seqExpr", + stmts: [{ kind: "exprStmt", expr: from, loc }], + result: { kind: "numLit", value: NaN, type: F64, loc }, + type: F64, + loc, + }, + ]; + if (from.type.kind !== "f64") lowerer.noLowering(`.${name} with a non-number fromIndex`, call); + return [needle, from]; +} + +const ELEMENT_SEARCHES: Readonly> = { + indexOf: "indexOfElem", + lastIndexOf: "lastIndexOfElem", + includes: "includesElem", +}; + +/** Whether a union has a Buffer arm, under any alias name: each arm's own + * symbol names it. */ +function hasBufferArm(type: ts.Type): boolean { + const arms = type.flags & ts.TypeFlags.Union ? constituentTypes(type) : [type]; + return arms.some((arm) => { + const symbol = arm.getSymbol(); + return symbol !== undefined && ts.symbolName(symbol) === "Buffer"; + }); +} + +/** The element-kind-generic typed-array methods on a union of typed + * arrays (indexed-unions.ts): the arguments lower as for one typed array, + * and each arm runs the method on its own receiver. Null for the methods + * that need a narrowing to one kind first. */ +function lowerUnionBytesMethodCall( + lowerer: Lowerer, + call: ts.CallExpression, + access: ts.PropertyAccessExpression, + name: string, +): IrExpr | null { + if (isJsSourceFile(ts.getSourceFileOfNode(call))) return null; + // A Buffer arm's methods differ from a typed array's (slice aliases, fill + // checks its range, searches take strings and wrap numbers), so such a + // union narrows to its arms first. + if (hasBufferArm(lowerer.typeOf(access.expression))) return null; + const nodes = call.arguments.nodes; + if (nodes.some(ts.isSpreadElement)) return null; + const loc = locOf(call); + const num = (value: number): IrExpr => ({ kind: "numLit", value, type: F64, loc }); + const optional = (i: number, fallback: IrExpr, type: IrType = F64): IrExpr => + nodes[i] ? lowerOptionalArgument(lowerer, nodes[i]!, type, fallback) : fallback; + let method: IrBytesIntrinsicMethod; + let args: () => IrExpr[]; + let result: "receiver" | IrType; + if ((name === "slice" || name === "subarray") && nodes.length <= 2) { + method = name; + args = () => [optional(0, num(0)), optional(1, num(Infinity))]; + result = "receiver"; + } else if (name === "fill" && nodes.length <= 3) { + method = "fillElem"; + args = () => [optional(0, num(0)), optional(1, num(0)), optional(2, num(Infinity))]; + result = "receiver"; + } else if (name === "copyWithin" && nodes.length <= 3) { + method = "copyWithin"; + args = () => [optional(0, num(0)), optional(1, num(0)), optional(2, num(Infinity))]; + result = "receiver"; + } else if (name === "toReversed" && nodes.length === 0) { + method = "toReversed"; + args = () => []; + result = "receiver"; + } else if (Object.hasOwn(ELEMENT_SEARCHES, name) && (nodes.length === 1 || nodes.length === 2)) { + method = ELEMENT_SEARCHES[name]!; + args = () => elementSearchArgs(lowerer, call, name); + result = name === "includes" ? BOOL : F64; + } else if (name === "join" && nodes.length <= 1) { + method = "join"; + args = () => [optional(0, { kind: "strLit", value: ",", type: STRING, loc }, STRING)]; + result = STRING; + } else if (name === "set" && (nodes.length === 1 || nodes.length === 2)) { + const source = lowerer.mapTypeOf(lowerer.typeOf(nodes[0]!)); + method = source?.kind === "bytes" ? "setFrom" : "setFromDyn"; + args = () => { + const src = lowerer.lowerExpr(nodes[0]!); + const first = src.type.kind === "bytes" ? src : lowerer.coerceInto(nodes[0]!, src, DYN); + return nodes.length === 2 ? [first, optional(1, num(0))] : [first]; + }; + result = VOID; + } else return null; + const receiver = lowerer.lowerExpr(access.expression); + const arms = indexedUnionArms(lowerer, receiver.type); + if (!arms || !allBytesArms(arms)) return null; + return lowerIndexedUnionMethod(lowerer, receiver, arms, method, args(), result, loc); +} + export function lowerBytesMethodCall( lowerer: Lowerer, call: ts.CallExpression, @@ -1040,6 +1155,9 @@ export function lowerBytesMethodCall( if (lowerer.chainBlocked(access, call)) return null; const name = access.name.text; const receiverIr = lowerer.mapTypeOf(lowerer.typeOf(access.expression)); + const unionArms = receiverIr ? indexedUnionArms(lowerer, receiverIr) : null; + if (unionArms && allBytesArms(unionArms) && lowerer.isStdlibMember(access)) + return lowerUnionBytesMethodCall(lowerer, call, access, name); if (receiverIr?.kind !== "bytes") return null; if (!lowerer.isStdlibMember(access)) return null; const loc = locOf(call); @@ -1086,6 +1204,29 @@ export function lowerBytesMethodCall( if (value) return value; } } + // TypedArray indexOf / lastIndexOf / includes (the Buffer-declared forms, + // which also take string and Buffer needles, lowered above). + if ( + Object.hasOwn(ELEMENT_SEARCHES, name) && + !lowerer.checker + .getSymbolAtLocation(access.name) + ?.declarations.some( + (d) => ts.isInterfaceDeclaration(d.parent) && d.parent.name.text === "Buffer", + ) + ) { + if (nArgs < 1 || nArgs > 2 || call.arguments.nodes.some(ts.isSpreadElement)) { + lowerer.noLowering(`.${name} with ${nArgs} arguments on typed arrays`, call); + } + const receiver = lowerer.lowerExprExpecting(access.expression, receiverIr); + return { + kind: "bytesIntrinsic", + method: ELEMENT_SEARCHES[name]!, + receiver, + args: elementSearchArgs(lowerer, call, name), + type: name === "includes" ? BOOL : F64, + loc, + }; + } if (name === "toReversed") { if (nArgs !== 0) { lowerer.noLowering(`.toReversed with ${nArgs} arguments on typed arrays`, call); diff --git a/packages/compiler/src/frontend/lowering/expressions/array-literals.ts b/packages/compiler/src/frontend/lowering/expressions/array-literals.ts index 6c7ce814e..c1b54a417 100644 --- a/packages/compiler/src/frontend/lowering/expressions/array-literals.ts +++ b/packages/compiler/src/frontend/lowering/expressions/array-literals.ts @@ -1,4 +1,5 @@ /* Array literals. */ +import { indexedUnionArms, lowerIndexedUnionToArray } from "../indexed-unions.js"; import * as ts from "../../ts7/adapter.js"; import { type Lowerer, neverTaintedJsType } from "../lowerer.js"; import { notIterableSpelling } from "../iterable-spelling.js"; @@ -504,6 +505,10 @@ export function lowerArrayLiteral( loc: locOf(el), }; } + // A union of typed arrays and number arrays (indexed-unions.ts): + // each arm's elements as a number[]. + const indexedArms = indexedUnionArms(lowerer, src.type); + if (indexedArms) src = lowerIndexedUnionToArray(lowerer, src, indexedArms, locOf(el)); // `[...obj]` over a class whose [Symbol.iterator] is a generator // method spreads the generator that method returns. src = classGeneratorIterable(lowerer, src) ?? src; diff --git a/packages/compiler/src/frontend/lowering/expressions/binary.ts b/packages/compiler/src/frontend/lowering/expressions/binary.ts index ab5ddeab6..a0475cffa 100644 --- a/packages/compiler/src/frontend/lowering/expressions/binary.ts +++ b/packages/compiler/src/frontend/lowering/expressions/binary.ts @@ -244,37 +244,38 @@ function lowerLooseNullCompare( // No unit arms: never null-ish (defensive — the fold below). return { kind: "boolLit", value: negated, type: BOOL, loc }; } - const isTag = (tag: number): IrExpr => ({ + const isTag = (tag: number, value: IrExpr): IrExpr => ({ kind: "unionIsTag", unionId: ut.unionId, tag, negated, - value: other, + value, type: BOOL, loc, }); - if (tags.length === 1) return isTag(tags[0]!); + if (tags.length === 1) return isTag(tags[0]!, other); // Both null AND undefined arms: tag-in-set as a short-circuit pair - // (De Morgan for `!=`). The operand IrExpr rides both tests, so the - // backend emits it per test — restricted to re-emittable pure reads; - // anything effectful gets its own actionable fence (the generic - // SC1040 hint would wrongly suggest `== null` as the fix). + // (De Morgan for `!=`). The operand rides both tests, so an operand + // that is not a plain read (`m.get(k)! == null`) is evaluated once + // into a hidden local first. + let value = other; + let prefix: IrStmt[] = []; if (!isSafeToRepeat(other)) { - lowerer.unsupported( - "SC1090", - expr, - `'== null' / '!= null' on a '${lowerer.fmt(ut)}' value that isn't a plain read ` + - `(both unit arms need the operand twice — bind it to a const first)`, - ); + const tmp = lowerer.declareHiddenLocal("%nullish", ut); + value = varRef(tmp.id, ut, loc); + prefix = [{ kind: "varDecl", localId: tmp.id, init: other, loc }]; } - return { + const test: IrExpr = { kind: "logical", op: negated ? "&&" : "||", - left: isTag(tags[0]!), - right: isTag(tags[1]!), + left: isTag(tags[0]!, value), + right: isTag(tags[1]!, value), type: BOOL, loc, }; + return prefix.length === 0 + ? test + : { kind: "seqExpr", stmts: prefix, result: test, type: BOOL, loc }; } if (other.type.kind === "void") { return null; // no static tag to test — keep the fence diff --git a/packages/compiler/src/frontend/lowering/expressions/element-access.ts b/packages/compiler/src/frontend/lowering/expressions/element-access.ts index 0b6b41f3e..9ac6a04b6 100644 --- a/packages/compiler/src/frontend/lowering/expressions/element-access.ts +++ b/packages/compiler/src/frontend/lowering/expressions/element-access.ts @@ -45,6 +45,7 @@ import { lowerDynMemberAssignment, lowerOptionalArrayIndexRead, lowerOptionalNumber, + assertedReadObservesUndefined, recordKeyResultOk, representedClassFieldTarget, runtimeOptionalElementKey, @@ -71,6 +72,13 @@ import { isClassCallback } from "../class-callbacks.js"; import { isKeyedFieldAccess } from "./keyed-field-targets.js"; import { lowerFieldCompoundValue } from "./updates.js"; import { readsHeldEvolvingArray } from "../lower-stmts.js"; +import { + type IndexedArm, + indexedUnionArms, + lowerIndexedUnionNumberRead, + lowerIndexedUnionRead, + lowerIndexedUnionWrite, +} from "../indexed-unions.js"; import { lowerBufferPrototypeMember } from "../containers/bytes.js"; /** `a[i]` reads. Only f64 indices into array receivers are modeled; JS @@ -302,6 +310,31 @@ export function lowerElementAccess(lowerer: Lowerer, expr: ts.ElementAccessExpre } } + // An element read of a union of typed arrays and number arrays: each + // arm's own read, dispatched on the tag (indexed-unions.ts). + const indexedArms = receiverIr ? indexedUnionArms(lowerer, receiverIr) : null; + if (indexedArms && receiverIr && !isJsSourceFile(ts.getSourceFileOfNode(expr))) { + let recv = lowerer.lowerExpr(expr.expression); + if (recv.type.kind === "dyn") recv = lowerer.coerceInto(expr.expression, recv, receiverIr); + const arms = indexedUnionArms(lowerer, recv.type); + if (arms) { + const index = lowerOptionalNumber( + lowerer, + lowerer.lowerExpr(expr.argumentExpression), + locOf(expr.argumentExpression), + expr.argumentExpression, + ); + if (index.type.kind !== "f64") + lowerer.unsupported("SC1090", expr.argumentExpression, "indexing with non-number keys"); + if ( + (ts.isNonNullExpression(expr.parent) && expr.parent.expression === expr) || + lowerer.nanCodedReads?.isNumericRead(expr) === true + ) + return lowerIndexedUnionNumberRead(lowerer, recv, arms, index, locOf(expr)); + return lowerIndexedUnionRead(lowerer, recv, arms, index, locOf(expr)); + } + } + // Typed-array element read `b[i]` — like arrayGet with a scalar // result; any invalid index traps (the array discipline; JS would // read undefined — divergence 4's policy). @@ -349,13 +382,18 @@ export function lowerElementAccess(lowerer: Lowerer, expr: ts.ElementAccessExpre if (index.type.kind !== "f64") { lowerer.unsupported("SC1090", expr.argumentExpression, "indexing with non-number keys"); } - // `t[i]!` asserts presence: the numeric element read (NaN when - // invalid). Every other read answers undefined for an invalid index, - // like Node. + // `t[i]!` performs no runtime check, but its static type is a number: + // it takes the numeric element read (NaN when invalid), except where + // the value reaches a use that tells undefined from NaN (an equality, a + // string conversion, `typeof`, an array element), which reads undefined + // for an invalid index like `t[i]`. Every other read answers undefined + // for an invalid index, like Node. // A read whose every consumer treats undefined like NaN (see // nan-coded-reads.ts) is the same plain numeric read. if ( - (ts.isNonNullExpression(expr.parent) && expr.parent.expression === expr) || + (ts.isNonNullExpression(expr.parent) && + expr.parent.expression === expr && + !assertedReadObservesUndefined(lowerer, expr.parent)) || lowerer.nanCodedReads?.isNumericRead(expr) === true ) { return { @@ -1521,6 +1559,9 @@ export function lowerElementCompoundParts( }); return { expr: { kind: "seqExpr", stmts, result: value, type: DYN, loc }, stmts: null }; } + const indexedArms = indexedUnionArms(lowerer, checked.type); + if (indexedArms && !isJsSourceFile(ts.getSourceFileOfNode(expr))) + return lowerIndexedUnionCompound(lowerer, expr, op, checked, indexedArms); const receiverType = checked.type.kind === "array" || checked.type.kind === "bytes" ? checked.type @@ -1705,6 +1746,54 @@ export function lowerElementCompoundParts( }; } +/** `u[i] op= v` on a union of typed arrays and number arrays: the + * receiver and index evaluate once, the old element reads as a number (NaN + * for an invalid index, as in the typed-array form), and the result is + * stored through the union's element write. */ +function lowerIndexedUnionCompound( + lowerer: Lowerer, + expr: ts.BinaryExpression, + op: CompoundOp, + receiver: IrExpr, + arms: readonly IndexedArm[], +): { expr: IrExpr | null; stmts: IrStmt[] | null } { + const target = expr.left as ts.ElementAccessExpression; + const loc = locOf(expr); + const index = lowerOptionalIndex( + lowerer, + lowerer.lowerExpr(target.argumentExpression), + locOf(target.argumentExpression), + target.argumentExpression, + ); + if (index.type.kind !== "f64") + lowerer.unsupported("SC1090", target.argumentExpression, "indexing with non-number keys"); + const receiverLocal = lowerer.declareHiddenLocal("%compoundArray", receiver.type); + const indexLocal = lowerer.declareHiddenLocal("%compoundIndex", F64); + const receiverRef = (): IrExpr => varRef(receiverLocal.id, receiver.type, loc); + const indexRef = (): IrExpr => varRef(indexLocal.id, F64, loc); + const oldValue = lowerIndexedUnionNumberRead(lowerer, receiverRef(), arms, indexRef(), loc); + const rhs = lowerOptionalNumber(lowerer, lowerer.lowerExpr(expr.right), loc); + if (rhs.type.kind !== "f64") compoundUnsupported(lowerer, expr, op, F64, rhs.type); + const computed: IrExpr = { kind: "bin", op, left: oldValue, right: rhs, type: F64, loc }; + const resultLocal = lowerer.declareHiddenLocal("%compoundResult", F64); + const resultRef = (): IrExpr => varRef(resultLocal.id, F64, loc); + return { + expr: { + kind: "seqExpr", + stmts: [ + { kind: "varDecl", localId: receiverLocal.id, init: receiver, loc }, + { kind: "varDecl", localId: indexLocal.id, init: index, loc }, + { kind: "varDecl", localId: resultLocal.id, init: computed, loc }, + lowerIndexedUnionWrite(lowerer, receiverRef(), arms, indexRef(), resultRef(), loc), + ], + result: resultRef(), + type: F64, + loc, + }, + stmts: null, + }; +} + /** ToString of one stabilized `string[]` element read for `+=`: a missing * element concatenates as "undefined". */ function arrayStringOperand(arr: IrExpr, index: IrExpr, loc: SrcLoc): IrExpr { @@ -2246,6 +2335,26 @@ export function lowerElementWrite(lowerer: Lowerer, expr: ts.BinaryExpression): }; } } + // An element write into a union of typed arrays and number arrays + // (indexed-unions.ts). + const indexedArms = receiverIr ? indexedUnionArms(lowerer, receiverIr) : null; + if (indexedArms && receiverIr && !isJsSourceFile(ts.getSourceFileOfNode(expr))) { + let recv = lowerer.lowerExpr(target.expression); + if (recv.type.kind === "dyn") recv = lowerer.coerceInto(target.expression, recv, receiverIr); + const arms = indexedUnionArms(lowerer, recv.type); + if (arms) { + const index = lowerOptionalNumber( + lowerer, + lowerer.lowerExpr(target.argumentExpression), + locOf(target.argumentExpression), + target.argumentExpression, + ); + if (index.type.kind !== "f64") + lowerer.unsupported("SC1090", target.argumentExpression, "indexing with non-number keys"); + const value = lowerer.lowerExprExpecting(expr.right, F64); + return lowerIndexedUnionWrite(lowerer, recv, arms, index, value, locOf(expr)); + } + } if (receiverIr?.kind !== "array") { lowerer.unsupported("SC1090", target, "assignment to non-array elements"); } diff --git a/packages/compiler/src/frontend/lowering/expressions/identifiers.ts b/packages/compiler/src/frontend/lowering/expressions/identifiers.ts index 41f915f15..f7ba7a115 100644 --- a/packages/compiler/src/frontend/lowering/expressions/identifiers.ts +++ b/packages/compiler/src/frontend/lowering/expressions/identifiers.ts @@ -25,6 +25,11 @@ import { } from "../../../ir/ir.js"; import { lowerNodeModuleIdentifier } from "../lower-node-module.js"; import { lowerCjsExportsObjectValue } from "../cjs-exports-object.js"; +import { + splitRequireBindingOfIdent, + wholeExportSymbolOfModule, + wholeExportValue, +} from "../cjs-inline-require.js"; import { captureContextArguments } from "../function-context.js"; import { argumentsOwner, typedArgumentsCandidate } from "../typed-arguments.js"; import { @@ -979,6 +984,27 @@ export function lowerIdentifierExpr(lowerer: Lowerer, expr: ts.Identifier, loc: // Client`): the member holds that binding's value. const memberAlias = cjsMemberAliasValueOf(lowerer, expr); if (memberAlias !== null) return lowerer.lowerExpr(memberAlias); + // `var m; m = require("./x")` as a bare value: a whole-export target is + // the exported value; a table target has no first-class module object. + { + const split = splitRequireBindingOfIdent(lowerer, expr); + if (split !== null) { + if (wholeExportSymbolOfModule(lowerer, split.dep) !== null) { + const value = wholeExportValue(lowerer, split.dep, expr); + if (value !== null) return value; + lowerer.unsupported( + "SC1090", + expr, + `the whole export of '${split.spec}' as a value (its 'module.exports =' value has no static representation)`, + ); + } + lowerer.unsupported( + "SC1090", + expr, + `the exports object of '${split.spec}' as a value (its exports compile to a static table: read require(${JSON.stringify(split.spec)}).member directly)`, + ); + } + } // Preflight guarantees no unresolved identifiers; anything else here // is a blocked declaration's binding (the SC2004 cascade) or a // binding form we don't model yet. diff --git a/packages/compiler/src/frontend/lowering/expressions/property-access.ts b/packages/compiler/src/frontend/lowering/expressions/property-access.ts index b542fa303..dbbce5d0d 100644 --- a/packages/compiler/src/frontend/lowering/expressions/property-access.ts +++ b/packages/compiler/src/frontend/lowering/expressions/property-access.ts @@ -1,4 +1,5 @@ /* Property reads (`a.b`): lowerExprInner's property-access branch, intrinsic and union properties, field reads and targets, and match-group reads. */ +import { indexedUnionArms, lowerIndexedUnionMember } from "../indexed-unions.js"; import { keyedHelperName } from "../stable-names.js"; import { staticallySelected } from "../static-typeof.js"; import * as ts from "../../ts7/adapter.js"; @@ -3400,6 +3401,13 @@ export function lowerUnionProperty( loc: locOf(expr), }; } + // A union of typed arrays and number arrays: each arm's own length + // (and, for typed arrays only, byteLength, byteOffset, BYTES_PER_ELEMENT). + const indexedArms = indexedUnionArms(lowerer, value.type); + if (indexedArms) { + const member = lowerIndexedUnionMember(lowerer, value, indexedArms, field, locOf(expr)); + if (member) return member; + } lowerer.unsupported( "SC1090", expr, diff --git a/packages/compiler/src/frontend/lowering/expressions/updates.ts b/packages/compiler/src/frontend/lowering/expressions/updates.ts index 7cc77a2db..bdcd94a44 100644 --- a/packages/compiler/src/frontend/lowering/expressions/updates.ts +++ b/packages/compiler/src/frontend/lowering/expressions/updates.ts @@ -1,4 +1,9 @@ /* Increment, decrement and prefix unary operators, and compound field updates. */ +import { + indexedUnionArms, + lowerIndexedUnionNumberRead, + lowerIndexedUnionWrite, +} from "../indexed-unions.js"; import * as ts from "../../ts7/adapter.js"; import { lowerOptionalIndex, @@ -390,6 +395,39 @@ export function lowerIncDec( loc, })); } + // A union of typed arrays and number arrays (indexed-unions.ts): the + // element read as a number and the union's element write. + const indexedArms = indexedUnionArms(lowerer, raw.type); + if ( + ts.isElementAccessExpression(access) && + indexedArms && + !isJsSourceFile(ts.getSourceFileOfNode(expr)) + ) { + const receiver = save(raw, "%incrementArray"); + const index = save( + lowerOptionalIndex( + lowerer, + lowerer.lowerExpr(access.argumentExpression), + locOf(access.argumentExpression), + access.argumentExpression, + ), + "%incrementIndex", + ); + if (index.type.kind !== "f64") + lowerer.unsupported("SC1090", access, "incrementing non-number array keys"); + return finish( + lowerIndexedUnionNumberRead(lowerer, receiver, indexedArms, index, loc), + (value) => + lowerIndexedUnionWrite( + lowerer, + receiver, + indexedArms, + index, + lowerer.coerceInto(access, value, F64), + loc, + ), + ); + } // A TS member statically typed number on a checked-dynamic receiver (a // class-backed protocol view): the expanded form `o.v = o.v + 1`, its // read checked into number like any other read of the member. diff --git a/packages/compiler/src/frontend/lowering/function-returns.ts b/packages/compiler/src/frontend/lowering/function-returns.ts index dde109ea7..6d0989e2b 100644 --- a/packages/compiler/src/frontend/lowering/function-returns.ts +++ b/packages/compiler/src/frontend/lowering/function-returns.ts @@ -17,6 +17,7 @@ import { PoisonError, dynFallbackType } from "./lowerer.js"; import { functionCanReturnUndefined } from "../function-completion.js"; import { jsBindingAppendsOnly, jsBindingHasOpenWrites } from "./lower-stmts.js"; import type { FnCtx } from "./function-context.js"; +import { returnsGuessedOverloadValue } from "./overload-choice.js"; /** Keep the conservative completion rule shared by return construction * and inference. Nested control flow may still make completion unreachable. */ @@ -256,6 +257,22 @@ export function declaredReturnType( return decl.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword) ? { kind: "promise", inner: DYN } : DYN; + // A JS function returning a value whose type rests on an undecided + // overload (guessedOverloadValue): the inferred result is the first + // overload's, which the returned value need not have. + if ( + isJsSourceFile(ts.getSourceFileOfNode(decl)) && + !decl.type && + !decl.asteriskToken && + !hasExplicitJsDocReturn(decl) && + mappedReturn !== null && + mappedReturn.kind !== "dyn" && + !(mappedReturn.kind === "promise" && mappedReturn.inner.kind === "dyn") && + returnsGuessedOverloadValue(lowerer, decl) + ) + return decl.modifiers?.nodes.some((modifier) => modifier.kind === ts.SyntaxKind.AsyncKeyword) + ? { kind: "promise", inner: DYN } + : DYN; // JS inference assigns Number to arithmetic over any, although the // runtime operands can both be BigInts. Preserve that native result. if ( diff --git a/packages/compiler/src/frontend/lowering/indexed-unions.ts b/packages/compiler/src/frontend/lowering/indexed-unions.ts new file mode 100644 index 000000000..774f3aef3 --- /dev/null +++ b/packages/compiler/src/frontend/lowering/indexed-unions.ts @@ -0,0 +1,569 @@ +import { keyedHelperName } from "./stable-names.js"; +import { helperLoc, varRef } from "../../ir/build.js"; +import { + BOOL, + BYTES_ELEMENT_SIZE, + F64, + VOID, + type IrBytesIntrinsicMethod, + type IrExpr, + type IrFunction, + type IrStmt, + type IrType, + type SrcLoc, + typeKey, +} from "../../ir/ir.js"; +import { everyExprChild, everyStmtChild } from "../../ir/traverse.js"; +import { arrayNumberRead, lowerSafeBytesRead, lowerSafeIndexRead } from "./array-values.js"; +import type { Lowerer } from "./lowerer.js"; + +/** Unions of number-indexed containers: typed arrays of any element kind + * (`Uint8Array | Uint16Array | Uint32Array`, as lru-cache picks by size) + * and `number[]` arms. + * + * The union keeps its ordinary tagged representation. Each operation on it + * lowers to a lifted helper per union and operation that tests the tag, + * narrows to the arm and runs the arm's own operation: the inline load or + * store of a typed array's element kind, or the dense read or write of a + * number array. The helpers are small, so LLVM inlines them, and a loop + * over one union value tests a loop-invariant tag. */ + +/** One arm: its tag and its type (bytes, or an array of numbers). */ +export interface IndexedArm { + tag: number; + type: IrType & ({ kind: "bytes" } | { kind: "array" }); +} + +/** The arms of a union whose every arm is a typed array or a `number[]`, + * or null. Unions with any other arm (undefined included) are not + * indexed unions: their reads need a narrowing first. */ +export function indexedUnionArms(lowerer: Lowerer, type: IrType): IndexedArm[] | null { + if (type.kind !== "union") return null; + const arms = lowerer.unions.get(type.unionId)?.arms; + if (!arms || arms.length < 2) return null; + const result: IndexedArm[] = []; + for (const [tag, arm] of arms.entries()) { + if (arm.kind === "bytes") result.push({ tag, type: arm }); + else if (arm.kind === "array" && arm.elem.kind === "f64") result.push({ tag, type: arm }); + else return null; + } + return result; +} + +/** Whether every arm is a typed array (so typed-array-only members such + * as `byteLength` apply). */ +export function allBytesArms(arms: readonly IndexedArm[]): boolean { + return arms.every((arm) => arm.type.kind === "bytes"); +} + +type ArmBody = (receiver: IrExpr, arm: IndexedArm, args: readonly IrExpr[]) => IrStmt[]; + +/** The helper `name(u, ...args)`: for each arm but the last, a tag test + * that runs the arm's statements; the last arm's statements run without a + * test (the union holds one of its arms). */ +function dispatchHelper( + lowerer: Lowerer, + key: string, + prefix: string, + union: IrType, + arms: readonly IndexedArm[], + params: readonly { name: string; type: IrType }[], + returnType: IrType, + body: ArmBody, + loc: SrcLoc, +): string { + const existing = lowerer.arrHofHelpers.get(key); + if (existing) return existing; + const name = keyedHelperName(lowerer, prefix, key); + lowerer.arrHofHelpers.set(key, name); + const at = helperLoc(loc); + if (union.kind !== "union") throw new Error("indexed-union helper over a non-union"); + const u = varRef("u.0", union, at); + const args = params.map((p) => varRef(`${p.name}.0`, p.type, at)); + const stmts: IrStmt[] = []; + arms.forEach((arm, i) => { + const receiver: IrExpr = { + kind: "unionNarrow", + unionId: union.unionId, + tag: arm.tag, + value: u, + type: arm.type, + loc: at, + }; + const armStmts = body(receiver, arm, args); + if (i === arms.length - 1) { + stmts.push(...armStmts); + return; + } + stmts.push({ + kind: "if", + cond: { + kind: "unionIsTag", + unionId: union.unionId, + tag: arm.tag, + negated: false, + value: u, + type: BOOL, + loc: at, + }, + then: armStmts, + else_: null, + loc: at, + }); + }); + const fn: IrFunction = { + name, + params: [ + { localId: "u.0", name: "u", type: union }, + ...params.map((p) => ({ localId: `${p.name}.0`, name: p.name, type: p.type })), + ], + returnType, + locals: [ + { id: "u.0", name: "u", type: union, mutable: false }, + ...params.map((p) => ({ id: `${p.name}.0`, name: p.name, type: p.type, mutable: false })), + ], + body: stmts, + loc: at, + }; + lowerer.liftedFns.push(fn); + return name; +} + +const returning = (value: IrExpr, loc: SrcLoc): IrStmt[] => [{ kind: "return", value, loc }]; + +/** `u[i]` read as an element or undefined (an invalid index), as the + * typed-array and number-array reads answer. */ +export function lowerIndexedUnionRead( + lowerer: Lowerer, + receiver: IrExpr, + arms: readonly IndexedArm[], + index: IrExpr, + loc: SrcLoc, +): IrExpr { + const resultT = lowerer.withUndefinedArm(F64); + const key = `idxUnion:get:${unionKey(receiver.type)}`; + const name = dispatchHelper( + lowerer, + key, + "%union.idxOr", + receiver.type, + arms, + [{ name: "i", type: F64 }], + resultT, + (arm, info, [i]) => + returning( + info.type.kind === "bytes" + ? lowerSafeBytesRead(lowerer, arm, i!, loc) + : lowerSafeIndexRead(lowerer, arm, i!, loc)!, + loc, + ), + loc, + ); + const numeric = indexedUnionNumberHelper(lowerer, receiver.type, arms, loc); + lowerer.indexedUnionNumericTwins.set(name, numeric); + return { kind: "call", callee: name, args: [receiver, index], type: resultT, loc }; +} + +/** `u[i]` read as a number: an invalid index reads as NaN, which is + * ToNumber(undefined). */ +export function lowerIndexedUnionNumberRead( + lowerer: Lowerer, + receiver: IrExpr, + arms: readonly IndexedArm[], + index: IrExpr, + loc: SrcLoc, +): IrExpr { + if (inlineDispatch(receiver, [index])) + return inlineArms(receiver, arms, F64, (arm, info) => numberRead(arm, info, index, loc), loc); + const name = indexedUnionNumberHelper(lowerer, receiver.type, arms, loc); + return { kind: "call", callee: name, args: [receiver, index], type: F64, loc }; +} + +function numberRead(arm: IrExpr, info: IndexedArm, index: IrExpr, loc: SrcLoc): IrExpr { + return info.type.kind === "bytes" + ? { + kind: "bytesIntrinsic", + method: "get", + receiver: arm, + args: [index], + type: F64, + loc, + invalidNaN: true, + } + : arrayNumberRead(arm, index, loc); +} + +function indexedUnionNumberHelper( + lowerer: Lowerer, + union: IrType, + arms: readonly IndexedArm[], + loc: SrcLoc, +): string { + return dispatchHelper( + lowerer, + `idxUnion:num:${unionKey(union)}`, + "%union.getNumber", + union, + arms, + [{ name: "i", type: F64 }], + F64, + (arm, info, [i]) => returning(numberRead(arm, info, i!, loc), loc), + loc, + ); +} + +/** The numeric twin of an indexed-union read helper call, or null. */ +export function indexedUnionNumericTwin(lowerer: Lowerer, call: IrExpr): IrExpr | null { + if (call.kind !== "call") return null; + const twin = lowerer.indexedUnionNumericTwins.get(call.callee); + return twin === undefined ? null : { ...call, callee: twin, type: F64 }; +} + +/** `u[i] = v` for a number `v`: each arm's element store (a typed array + * converts the number to its element kind and ignores an invalid index; a + * number array stores at the index). */ +export function lowerIndexedUnionWrite( + lowerer: Lowerer, + receiver: IrExpr, + arms: readonly IndexedArm[], + index: IrExpr, + value: IrExpr, + loc: SrcLoc, +): IrStmt { + // In place, the value evaluates before the arms read the receiver and + // index: only when it cannot rebind either. + if (inlineDispatch(receiver, [index]) && !rebinds(value, [receiver, index])) { + const union = receiver.type; + const valueLocal = lowerer.declareHiddenLocal("%elementValue", F64); + const v: IrExpr = { kind: "varRef", localId: valueLocal.id, type: F64, loc }; + let chain: IrStmt[] | null = null; + for (let i = arms.length - 1; i >= 0; i--) { + const info = arms[i]!; + const arm: IrExpr = { + kind: "unionNarrow", + unionId: union.kind === "union" ? union.unionId : "", + tag: info.tag, + value: receiver, + type: info.type, + loc, + }; + const store: IrStmt = + info.type.kind === "bytes" + ? { kind: "bytesSet", arr: arm, index, value: v, loc } + : { kind: "arraySet", arr: arm, index, value: v, loc }; + chain = + chain === null + ? [store] + : [ + { + kind: "if", + cond: { + kind: "unionIsTag", + unionId: union.kind === "union" ? union.unionId : "", + tag: info.tag, + negated: false, + value: receiver, + type: BOOL, + loc, + }, + then: [store], + else_: chain, + loc, + }, + ]; + } + return { + kind: "block", + body: [{ kind: "varDecl", localId: valueLocal.id, init: value, loc }, ...chain!], + loc, + }; + } + const name = dispatchHelper( + lowerer, + `idxUnion:set:${unionKey(receiver.type)}`, + "%union.idxSet", + receiver.type, + arms, + [ + { name: "i", type: F64 }, + { name: "v", type: F64 }, + ], + VOID, + (arm, info, [i, v]) => [ + info.type.kind === "bytes" + ? { kind: "bytesSet", arr: arm, index: i!, value: v!, loc } + : { kind: "arraySet", arr: arm, index: i!, value: v!, loc }, + { kind: "return", value: null, loc }, + ], + loc, + ); + return { + kind: "exprStmt", + expr: { kind: "call", callee: name, args: [receiver, index, value], type: VOID, loc }, + loc, + }; +} + +/** The members every arm answers: `length` for all, and `byteLength`, + * `byteOffset` and `BYTES_PER_ELEMENT` when every arm is a typed array. */ +export function lowerIndexedUnionMember( + lowerer: Lowerer, + receiver: IrExpr, + arms: readonly IndexedArm[], + member: string, + loc: SrcLoc, +): IrExpr | null { + const bytesOnly = member !== "length"; + if ( + member !== "length" && + member !== "byteLength" && + member !== "byteOffset" && + member !== "BYTES_PER_ELEMENT" + ) + return null; + if (bytesOnly && !allBytesArms(arms)) return null; + const memberOf = (arm: IrExpr, info: IndexedArm): IrExpr => + info.type.kind === "array" + ? { kind: "arrIntrinsic", method: "length", receiver: arm, args: [], type: F64, loc } + : member === "BYTES_PER_ELEMENT" + ? { kind: "numLit", value: BYTES_ELEMENT_SIZE[info.type.elem], type: F64, loc } + : { kind: "bytesIntrinsic", method: member, receiver: arm, args: [], type: F64, loc }; + if (inlineDispatch(receiver, [])) return inlineArms(receiver, arms, F64, memberOf, loc); + const name = dispatchHelper( + lowerer, + `idxUnion:${member}:${unionKey(receiver.type)}`, + `%union.${member}`, + receiver.type, + arms, + [], + F64, + (arm, info) => returning(memberOf(arm, info), loc), + loc, + ); + return { kind: "call", callee: name, args: [receiver], type: F64, loc }; +} + +function unionKey(type: IrType): string { + return type.kind === "union" ? String(type.unionId) : "?"; +} + +/** A typed-array method on a union whose every arm is a typed array: the + * arguments evaluate once in the caller, and each arm runs the same + * `bytesIntrinsic` on its own receiver. `result` "receiver" is a method + * that answers a typed array of the receiver's kind (subarray, slice, + * fill, ...): each arm wraps its answer back into the union. */ +export function lowerIndexedUnionMethod( + lowerer: Lowerer, + receiver: IrExpr, + arms: readonly IndexedArm[], + method: IrBytesIntrinsicMethod, + args: readonly IrExpr[], + result: "receiver" | IrType, + loc: SrcLoc, +): IrExpr { + const union = receiver.type; + if (union.kind !== "union") throw new Error("indexed-union method over a non-union"); + const resultT = result === "receiver" ? union : result; + const params = args.map((arg, i) => ({ name: `a${i}`, type: arg.type })); + const signature = args.map((arg) => typeKey(arg.type)).join(","); + const name = dispatchHelper( + lowerer, + `idxUnion:${method}(${signature}):${unionKey(union)}`, + `%union.${method}`, + union, + arms, + params, + resultT, + (arm, info, refs) => { + const call: IrExpr = { + kind: "bytesIntrinsic", + method, + receiver: arm, + args: [...refs], + type: result === "receiver" ? info.type : result, + loc, + }; + if (result === "receiver") + return returning( + { + kind: "unionWrap", + unionId: union.unionId, + tag: info.tag, + value: call, + type: union, + loc, + }, + loc, + ); + if (result.kind === "void") + return [ + { kind: "exprStmt", expr: call, loc }, + { kind: "return", value: null, loc }, + ]; + return returning(call, loc); + }, + loc, + ); + return { kind: "call", callee: name, args: [receiver, ...args], type: resultT, loc }; +} + +/** The elements of `u` as a `number[]`: a typed-array arm drains its + * elements into a fresh array. A number-array arm is the array itself for + * consumers that copy it (spreads), or with `fresh` a dense copy whose + * holes read as undefined (Array.from). */ +export function lowerIndexedUnionToArray( + lowerer: Lowerer, + receiver: IrExpr, + arms: readonly IndexedArm[], + loc: SrcLoc, + fresh = false, +): IrExpr { + const arrayT: IrType = { kind: "array", elem: F64 }; + const name = dispatchHelper( + lowerer, + `idxUnion:${fresh ? "from" : "toArray"}:${unionKey(receiver.type)}`, + fresh ? "%union.arrayFrom" : "%union.toArray", + receiver.type, + arms, + [], + arrayT, + (arm, info) => + returning( + info.type.kind === "bytes" + ? { + kind: "bytesIntrinsic", + method: "toArray", + receiver: arm, + args: [], + type: arrayT, + loc, + } + : fresh + ? { + kind: "arrIntrinsic", + method: "reverse", + receiver: { + kind: "arrIntrinsic", + method: "toReversed", + receiver: arm, + args: [], + type: arrayT, + loc, + }, + args: [], + type: arrayT, + loc, + } + : arm, + loc, + ), + loc, + ); + return { kind: "call", callee: name, args: [receiver], type: arrayT, loc }; +} + +/** Whether a dispatch can run in place instead of through a helper call: + * the receiver is a plain read, so testing and narrowing it once per arm + * reads the same value, and the other operands are plain reads or + * literals. The arms' own reads then stay visible to the integer range + * analysis (a loop bounded by `u.length` keeps an integer counter). */ +function inlineDispatch(receiver: IrExpr, operands: readonly IrExpr[]): boolean { + return ( + receiver.kind === "varRef" && operands.every((e) => e.kind === "varRef" || e.kind === "numLit") + ); +} + +/** Expressions that run no program code: reads, literals and operators + * over primitive values. */ +const CODE_FREE_EXPRS = new Set([ + "numLit", + "boolLit", + "strLit", + "unitLit", + "varRef", + "unary", + "logical", + "ternary", + "toBool", + "strEq", + "strCmp", + "arrayGet", + "arrayHas", + "arrayState", + "bytesIntrinsic", + "fieldGet", + "recordGet", + "unionNarrow", + "unionIsTag", + "unionDisc", + "upcast", + "nullish", +]); +const PRIMITIVE_OPERANDS = new Set(["f64", "bool", "string", "bigint"]); + +/** Whether evaluating `e` can rebind one of the plain reads `reads`: by + * assigning it, or by running program code (a call, a getter, a + * conversion) that could assign a captured binding. */ +function rebinds(e: IrExpr, reads: readonly IrExpr[]): boolean { + const ids = new Set(reads.flatMap((r) => (r.kind === "varRef" ? [r.localId] : []))); + let found = false; + const expr = (x: IrExpr): boolean => { + if ((x.kind === "assignExpr" || x.kind === "incDec") && ids.has(x.localId)) found = true; + else if (x.kind === "bin") { + if (!PRIMITIVE_OPERANDS.has(x.left.type.kind) || !PRIMITIVE_OPERANDS.has(x.right.type.kind)) + found = true; + } else if (x.kind === "call") { + // The union dispatch helpers only read and store elements. + if (!x.callee.startsWith("%union.")) found = true; + } else if (!CODE_FREE_EXPRS.has(x.kind)) found = true; + return !found && everyExprChild(x, expr, stmt); + }; + const stmt = (x: IrStmt): boolean => { + if ((x.kind === "assign" || x.kind === "varDecl") && ids.has(x.localId)) found = true; + return !found && everyStmtChild(x, expr, stmt); + }; + expr(e); + return found; +} + +/** The in-place form of a dispatch: a ternary chain over the arms' tags, + * the last arm untested. */ +function inlineArms( + receiver: IrExpr, + arms: readonly IndexedArm[], + type: IrType, + arm: (narrowed: IrExpr, info: IndexedArm) => IrExpr, + loc: SrcLoc, +): IrExpr { + const union = receiver.type; + if (union.kind !== "union") throw new Error("indexed-union dispatch over a non-union"); + const narrowed = (info: IndexedArm): IrExpr => ({ + kind: "unionNarrow", + unionId: union.unionId, + tag: info.tag, + value: receiver, + type: info.type, + loc, + }); + let result = arm(narrowed(arms[arms.length - 1]!), arms[arms.length - 1]!); + for (let i = arms.length - 2; i >= 0; i--) { + const info = arms[i]!; + result = { + kind: "ternary", + cond: { + kind: "unionIsTag", + unionId: union.unionId, + tag: info.tag, + negated: false, + value: receiver, + type: BOOL, + loc, + }, + then: arm(narrowed(info), info), + else_: result, + type, + loc, + }; + } + return result; +} diff --git a/packages/compiler/src/frontend/lowering/key-order-witness.test.ts b/packages/compiler/src/frontend/lowering/key-order-witness.test.ts index d68be96a8..21fe56815 100644 --- a/packages/compiler/src/frontend/lowering/key-order-witness.test.ts +++ b/packages/compiler/src/frontend/lowering/key-order-witness.test.ts @@ -29,7 +29,7 @@ interface Fixture { notes: KeyOrderNotes; record(fields: [string, IrType][], order: string[]): IrType & { kind: "record" }; literal(type: IrType, keys: string[], segments?: KeyOrderSegment[]): IrExpr; - run(body: IrStmt[]): IrFunction; + run(body: IrStmt[], name?: string): IrFunction; order(type: IrType & { kind: "record" }): string[] | undefined; } @@ -73,8 +73,8 @@ function fixture(): Fixture { segments ?? keys.map((name) => ({ kind: "key", name, definite: true })), ); }; - const run = (body: IrStmt[]): IrFunction => { - const fn: IrFunction = { name: "main", params: [], returnType: F64, locals: [], body, loc }; + const run = (body: IrStmt[], name = "main"): IrFunction => { + const fn: IrFunction = { name, params: [], returnType: F64, locals: [], body, loc }; applyKeyOrderWitnesses(lowerer, [fn]); return fn; }; @@ -706,7 +706,10 @@ test("a spread reads its source's order right after the literal evaluates the so /** `{ a, b }` with a declared table `["a", "b"]` and a literal `{ b, a }` * plus `{ ...value, a }` of the same shape, beside `extra`. */ -function selfCopy(extra: (f: Fixture, ab: IrType & { kind: "record" }) => IrStmt[]): string[] { +function selfCopy( + extra: (f: Fixture, ab: IrType & { kind: "record" }) => IrStmt[], + fnName = "main", +): string[] { const f = fixture(); const ab = f.record( [ @@ -716,11 +719,14 @@ function selfCopy(extra: (f: Fixture, ab: IrType & { kind: "record" }) => IrStmt ["a", "b"], ); const self: KeyOrderSegment = { kind: "spread", shapeId: ab.shapeId, maybeAbsent: false }; - f.run([ - decl("v", f.literal(ab, ["b", "a"])), - observe(f.literal(ab, ["a", "b"], [self, { kind: "key", name: "a", definite: true }])), - ...extra(f, ab), - ]); + f.run( + [ + decl("v", f.literal(ab, ["b", "a"])), + observe(f.literal(ab, ["a", "b"], [self, { kind: "key", name: "a", definite: true }])), + ...extra(f, ab), + ], + fnName, + ); return f.order(ab)!; } @@ -762,6 +768,31 @@ test("a replaceable method's checked result builds records when a replacement ma ).toEqual(["a", "b"]); }); +/** A native callback taking the shape, boxed for JavaScript. */ +const boxedCallback = (ab: IrType): IrExpr => ({ + kind: "dynFrom", + value: { + kind: "closure", + fnName: "callback", + captures: [], + type: { kind: "func", params: [ab], ret: { kind: "void" } }, + loc, + }, + type: { kind: "dyn" }, + loc, +}); + +test("a native callback boxed for JavaScript receives records JavaScript builds", () => { + expect(selfCopy((_, ab) => [observe(boxedCallback(ab))])).toEqual(["a", "b"]); +}); + +test("a class's prototype slots box its methods without building their parameters", () => { + expect(selfCopy((_, ab) => [observe(boxedCallback(ab))], "%prototype.data.Service")).toEqual([ + "b", + "a", + ]); +}); + test("a replaceable method's result keeps its witness through an IR rewrite", () => { expect( selfCopy((f, ab) => { diff --git a/packages/compiler/src/frontend/lowering/key-order-witness.ts b/packages/compiler/src/frontend/lowering/key-order-witness.ts index 6e65d6f6d..a5e635e04 100644 --- a/packages/compiler/src/frontend/lowering/key-order-witness.ts +++ b/packages/compiler/src/frontend/lowering/key-order-witness.ts @@ -292,6 +292,17 @@ function replacesWithoutRecords(lowerer: Lowerer, site: ts.Node): boolean { ); } +/** A compiler helper that boxes a class's own state for JavaScript's reads: + * its prototype data and the property and method dispatch over boxed + * instances. */ +function boxesOwnState(fnName: string): boolean { + return ( + fnName.startsWith("%prototype.data.") || + fnName.startsWith("%dyn.class.") || + fnName.startsWith("%class.") + ); +} + /** A type whose values are primitives (or void): it holds no record. */ function primitiveOnly(type: ts.Type): boolean { if (type.isUnionType()) return ts.constituentTypes(type).every(primitiveOnly); @@ -357,8 +368,18 @@ export function applyKeyOrderWitnesses(lowerer: Lowerer, fns: readonly IrFunctio * its checked field setters, each a witness of its own. A checked * function's parameters receive native values: a record parameter is * passed out, never built, though a callback among them receives values - * built from JavaScript again. */ - const shapesIn = (type: IrType, out: Set, seen: Set, produced = false): void => { + * built from JavaScript again. `built` false starts the walk at a value + * passed out (a native value boxed for JavaScript); `writes` false leaves + * out what JavaScript could write into the containers passed out, so the + * walk counts only what the functions among them receive. */ + const shapesIn = ( + type: IrType, + out: Set, + seen: Set, + produced = false, + built = true, + writes = true, + ): void => { const visit = (t: IrType, built: boolean): boolean => { const mark = built ? "" : "-"; // A container JavaScript builds converts into fresh native storage, so @@ -367,7 +388,7 @@ export function applyKeyOrderWitnesses(lowerer: Lowerer, fns: readonly IrFunctio // such as callbacks whose parameters it then builds (children passed // out). Those children count in both directions. const child = (type: IrType): boolean => { - visit(type, true); + if (built || writes) visit(type, true); if (!built) visit(type, false); return true; }; @@ -401,7 +422,7 @@ export function applyKeyOrderWitnesses(lowerer: Lowerer, fns: readonly IrFunctio } return everyTypeChild(t, child); }; - visit(type, true); + visit(type, built); }; const opaqueShapes = new Set(); const opaqueSeen = new Set(); @@ -412,6 +433,7 @@ export function applyKeyOrderWitnesses(lowerer: Lowerer, fns: readonly IrFunctio * declaration's order, the order their table holds. */ const declaredShapes = new Set(); const declaredSeen = new Set(); + const boxedSeen = new Set(); /** The checked result of a replaceable method call while every site that * can replace the method installs functions that return no record. */ const unchangedMethodResult = (node: IrExpr): boolean => { @@ -518,6 +540,16 @@ export function applyKeyOrderWitnesses(lowerer: Lowerer, fns: readonly IrFunctio case "jsonStringify": case "dynFrom": observedRoots.push(e.value.type); + // A native value the program hands to JavaScript: the callbacks it + // holds (itself, a field, an element) receive records JavaScript + // builds. The helpers that box the program's own state for + // JavaScript's reads (a class's prototype slots and property + // dispatch) hand out the class's methods, whose arguments the + // program's own calls pass as native values, as a replaceable + // method's result above. Writes through the boxed value are left + // out: reading a boxed value creates no record. + if (!boxesOwnState(fnName)) + shapesIn(e.value.type, runtimeShapes, boxedSeen, true, false, false); return; case "recordKeyGet": observedRoots.push(e.obj.type); diff --git a/packages/compiler/src/frontend/lowering/lower-assert.ts b/packages/compiler/src/frontend/lowering/lower-assert.ts index bc51a9382..b996abed7 100644 --- a/packages/compiler/src/frontend/lowering/lower-assert.ts +++ b/packages/compiler/src/frontend/lowering/lower-assert.ts @@ -1355,7 +1355,7 @@ function lowerAssertMatch( lowerer.noLowering(`${surface} with ${expr.arguments.nodes.length} arguments`, expr); } const s = lowerer.lowerExprExpecting(expr.arguments.nodes[0]!, STRING); - const re = lowerer.lowerExpr(expr.arguments.nodes[1]!); + const re = lowerExpectedValue(lowerer, expr.arguments.nodes[1]!); if (re.type.kind !== "regex") { lowerer.noLowering( `${surface} with a non-regex pattern`, @@ -1420,6 +1420,18 @@ function inErrorHierarchy(lowerer: Lowerer, className: string): boolean { return false; } +/** An expected string or regex: a value JavaScript stores checked-dynamic + * (an object literal's field, an untyped binding) converts to the string + * or regex its checker type names, so the comparison takes that arm. */ +function lowerExpectedValue(lowerer: Lowerer, node: ts.Expression): IrExpr { + const value = lowerer.lowerExpr(node); + if (value.type.kind !== "dyn") return value; + const expected = lowerer.mapTypeOf(lowerer.typeOf(node)); + return expected?.kind === "string" || expected?.kind === "regex" + ? lowerer.coerceToExpected(value, expected) + : value; +} + /** Classify the expected argument: string → message, regex value → the * regex test over String(error), an error-class identifier → instanceof, * an object LITERAL over name/message/code (string or regex values) → @@ -1436,7 +1448,7 @@ function classifyThrowsExpected( return { form: "message", msg: m.msg, hasMsg: m.hasMsg }; } if (expectedT?.kind === "regex") { - return { form: "regex", value: lowerer.lowerExpr(node) }; + return { form: "regex", value: lowerExpectedValue(lowerer, node) }; } const sym = ts.isIdentifier(node) ? lowerer.resolveValueSymbol(node) : null; const info = @@ -1509,7 +1521,7 @@ function classifyThrowsExpected( ); } const valueNode = ts.isPropertyAssignment(named) ? named.initializer : named.name; - const value = lowerer.lowerExpr(valueNode); + const value = lowerExpectedValue(lowerer, valueNode); if (value.type.kind === "string") { byId.set(id, { id, kind: "str", value, enameBake: null }); } else if (value.type.kind === "regex") { diff --git a/packages/compiler/src/frontend/lowering/lower-calls.ts b/packages/compiler/src/frontend/lowering/lower-calls.ts index 87102377c..644d03a45 100644 --- a/packages/compiler/src/frontend/lowering/lower-calls.ts +++ b/packages/compiler/src/frontend/lowering/lower-calls.ts @@ -261,6 +261,7 @@ import { completeArgs, } from "./call-arguments.js"; import { isThisParameter, type ParamShape } from "./call-signatures.js"; +import { dynamicOverloadChoice } from "./overload-choice.js"; import { lowerStringIteratorValue } from "./iterator-adapters.js"; import { checkedArmExtraction } from "./coercions/unions.js"; import { maybePromiseReturnStmt, promiseArmedUnionOf } from "./maybe-promise.js"; @@ -5508,6 +5509,9 @@ function reconcileOverloadReturn( expr: ts.CallExpression | ts.TaggedTemplateExpression, call: IrExpr, ): IrExpr { + // The checker's overload is a guess for a checked-dynamic argument + // another overload accepts: the implementation's value stands. + if (ts.isCallExpression(expr) && dynamicOverloadChoice(lowerer, expr)) return call; const rsig = lowerer.checker.getResolvedSignature(expr); const rdecl = rsig ? rsig.declaration : undefined; // Nominal covariant overrides share the base's return ABI, but retain diff --git a/packages/compiler/src/frontend/lowering/lower-classes.ts b/packages/compiler/src/frontend/lowering/lower-classes.ts index 2283c7dfb..eda277aaf 100644 --- a/packages/compiler/src/frontend/lowering/lower-classes.ts +++ b/packages/compiler/src/frontend/lowering/lower-classes.ts @@ -4408,6 +4408,14 @@ export function collectClassShapeInner( // INSTANTIATION prints its family's name — JS has one `Box`. jsName: jsNameOverride ?? decl.name?.text ?? "", ...(base ? { base: base.def.name } : {}), + ...(decl.members.nodes.some( + (member) => + ts.isPropertyDeclaration(member) && + !ts.isPrivateIdentifier(member.name) && + member.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.StaticKeyword), + ) + ? { ownStaticFields: true as const } + : {}), jsLength: ctor?.parameters?.nodes.findIndex( (parameter) => parameter.initializer || parameter.dotDotDotToken, diff --git a/packages/compiler/src/frontend/lowering/lower-console.ts b/packages/compiler/src/frontend/lowering/lower-console.ts index eec308342..b45218bd0 100644 --- a/packages/compiler/src/frontend/lowering/lower-console.ts +++ b/packages/compiler/src/frontend/lowering/lower-console.ts @@ -249,7 +249,8 @@ export function lowerConsoleArg( // inspect at the rest-args depth 2 (formatWithOptions) — scalar // kinds byte-exactly, boxed functions as [Function: name] / // [Function (anonymous)], composites through the dyn walk - // (insp.dyn). Never throws — Node's console.log never does. + // (insp.dyn). A value the inspector does not render throws the + // 'not supported yet' Error before anything is written. if (lowered.type.kind === "dyn") { return { kind: "libCall", diff --git a/packages/compiler/src/frontend/lowering/lower-exprs.ts b/packages/compiler/src/frontend/lowering/lower-exprs.ts index c1c5ef8c8..033f482d1 100644 --- a/packages/compiler/src/frontend/lowering/lower-exprs.ts +++ b/packages/compiler/src/frontend/lowering/lower-exprs.ts @@ -72,7 +72,7 @@ import { import { nsMemberIdentOf } from "./lower-namespaces.js"; import { bindingNeverReassigned } from "./binding-analysis.js"; import { implicitMonoFile } from "./generic-functions.js"; -import { lowerTaggedTemplate } from "./lower-calls.js"; +import { lowerPrimitiveUnionNumber, lowerTaggedTemplate } from "./lower-calls.js"; import { unitOnlyUnion } from "../type-mapper.js"; import { lowerYield } from "./lower-generators.js"; import { unionWideningTags } from "../../ir/analysis.js"; @@ -426,6 +426,12 @@ function lowerExprInner(lowerer: Lowerer, expr: ts.Expression): IrExpr { return inner; const use = runtimeOptionalUseOf(expr); if (runtimeOptionalAssertionErases(lowerer, expr, inner, use)) return inner; + // A destination that holds null or undefined keeps the value, as `!` + // does in JavaScript (`return cache.get(key)!` from a function that + // returns `T | null`); the destination's own coercion re-tags it. + if (assertionDestinationHoldsNullish(lowerer, expr, inner.type)) return inner; + const operand = assertionOperand(lowerer, expr, inner, target ?? null, loc); + if (operand) return operand; if (target && target.kind !== "union" && !typeEquals(target, inner.type)) { const helper = lowerer.narrowedArmHelper(inner.type.unionId, target, loc); if (helper) { @@ -933,6 +939,229 @@ export function assertedElementKeepsUndefined( ); } +/** Whether `node!` is a returned value, an arrow function's body or a call + * argument whose destination type (the return or parameter type) is `any` + * or `unknown` (as for `String(x!)` and `Number(x!)`) or holds null or + * undefined that the union `inner` holds and the assertion would remove. + * Bindings and assignments are left out: the checker narrows them to the + * asserted type for later reads. */ +function assertionDestinationHoldsNullish( + lowerer: Lowerer, + node: ts.NonNullExpression, + inner: IrType & { kind: "union" }, +): boolean { + const holdsNull = lowerer.armTag(inner.unionId, NULL_T) >= 0; + const holdsUndefined = lowerer.armTag(inner.unionId, UNDEFINED_T) >= 0; + if (!holdsNull && !holdsUndefined) return false; + let outer: ts.Expression = node; + while (ts.isParenthesizedExpression(outer.parent)) outer = outer.parent; + const parent = outer.parent; + const destination = + (ts.isReturnStatement(parent) && parent.expression === outer) || + (ts.isArrowFunction(parent) && parent.body === outer) || + ((ts.isCallExpression(parent) || ts.isNewExpression(parent)) && + parent.arguments?.nodes.includes(outer) === true); + if (!destination) return false; + const contextual = lowerer.checker.getContextualType(outer); + if (!contextual) return false; + const nullish = + ts.TypeFlags.Any | + ts.TypeFlags.Unknown | + (holdsNull ? ts.TypeFlags.Null : 0) | + (holdsUndefined && !optionalStdlibParameter(lowerer, parent, outer) + ? ts.TypeFlags.Undefined + : 0); + if ((contextual.flags & ts.TypeFlags.Union) === 0) return (contextual.flags & nullish) !== 0; + return constituentTypes(contextual).some((type) => (type.flags & nullish) !== 0); +} + +/** Whether `argument` of `call` binds an optional parameter of a standard + * library declaration (`decoder.decode(input?)`). The undefined such a + * parameter's type holds comes from its optionality, and the builtin + * lowerings read the argument as the declared type, so `x!` keeps the + * checked narrowing there. */ +function optionalStdlibParameter( + lowerer: Lowerer, + call: ts.Node, + argument: ts.Expression, +): boolean { + if (!ts.isCallExpression(call) && !ts.isNewExpression(call)) return false; + const declaration = lowerer.checker.getResolvedSignature(call)?.declaration; + if (declaration === undefined || !lowerer.isStdlibFile(ts.getSourceFileOfNode(declaration))) + return false; + const index = call.arguments?.nodes.indexOf(argument) ?? -1; + const parameter = declaration.parameters?.nodes[index]; + return ( + parameter !== undefined && + parameter.dotDotDotToken === undefined && + (parameter.questionToken !== undefined || parameter.initializer !== undefined) + ); +} + +/** `x!` as the operand of an operator that converts its operands: an + * arithmetic, bitwise, relational or equality operator, `+`, a compound + * assignment, a unary `-`, `+`, `~` or `!`, a template span, or an argument + * of a Math function. `!` performs no runtime check, + * so a value that still holds undefined or null reaches the operator, which + * converts it as JavaScript does: NaN or 0 in arithmetic, false in a + * comparison, "undefined" or "null" in a string. Returns the operand to + * use, or null where the assertion narrows as usual. A numeric use gets the + * value converted with ToNumber; other uses get the union itself. */ +function assertionOperand( + lowerer: Lowerer, + expr: ts.NonNullExpression, + inner: IrExpr, + target: IrType | null, + loc: SrcLoc, +): IrExpr | null { + if (inner.type.kind !== "union" || target === null || target.kind === "union") return null; + const arms = lowerer.unions.get(inner.type.unionId)?.arms; + if ( + !arms?.some(isUnitType) || + !arms.every( + (arm) => + arm.kind === "f64" || arm.kind === "string" || arm.kind === "bool" || isUnitType(arm), + ) + ) + return null; + // Array element reads keep their own handling of a missing element. A + // typed-array read is optional here only where its use tells undefined + // from NaN (assertedReadObservesUndefined). + let operand: ts.Expression = expr.expression; + while (ts.isParenthesizedExpression(operand)) operand = operand.expression; + if (ts.isElementAccessExpression(operand)) { + const kind = lowerer.mapTypeOf(lowerer.typeOf(operand.expression))?.kind; + if (kind === "array") return null; + } + const use = convertingUseOf(lowerer, expr); + if (use === null) return null; + if (use === "value") return inner; + return lowerPrimitiveUnionNumber(lowerer, inner, expr, loc); +} + +/** How the converting use of `x!` (see assertionOperand) reads it: + * "number" where the use applies ToNumber, "value" where the consumer + * lowers the union itself (strings, equality, truthiness), null for other + * uses. */ +function convertingUseOf(lowerer: Lowerer, expr: ts.NonNullExpression): "number" | "value" | null { + let outer: ts.Expression = expr; + while (ts.isParenthesizedExpression(outer.parent)) outer = outer.parent; + const parent = outer.parent; + if (ts.isTemplateSpan(parent)) return parent.expression === outer ? "value" : null; + if (ts.isTypeOfExpression(parent)) return "value"; + if (ts.isPrefixUnaryExpression(parent)) { + if (parent.operator === ts.SyntaxKind.ExclamationToken) return "value"; + return parent.operator === ts.SyntaxKind.MinusToken || + parent.operator === ts.SyntaxKind.PlusToken || + parent.operator === ts.SyntaxKind.TildeToken + ? "number" + : null; + } + if (ts.isCallExpression(parent) && parent.arguments.nodes.includes(outer)) { + const callee = parent.expression; + return ts.isPropertyAccessExpression(callee) && + stdlibGlobalNameOf(lowerer, callee.expression) === "Math" + ? "number" + : null; + } + if (!ts.isBinaryExpression(parent)) return null; + const op = parent.operatorToken.kind; + if (EQUALITY_OPERATORS.has(op)) return "value"; + const other = parent.left === outer ? parent.right : parent.left; + const isString = (node: ts.Expression): boolean => + (lowerer.typeOf(node).flags & ts.TypeFlags.StringLike) !== 0; + // With a string on either side, `+` concatenates and a comparison + // compares strings. `undefined + 1` and `undefined + undefined` are NaN, + // which a string-typed result cannot hold, so `+` takes the union only + // with a string partner that is not itself asserted. A partner that may + // hold a string or a number at run time (`any`, `unknown`) also gets the + // union, and `+` decides between concatenation and addition when it runs. + if (op === ts.SyntaxKind.PlusToken || op === ts.SyntaxKind.PlusEqualsToken) { + if (op === ts.SyntaxKind.PlusEqualsToken && parent.right !== outer) return null; + let partner = other; + while (ts.isParenthesizedExpression(partner)) partner = partner.expression; + if (isString(other)) return ts.isNonNullExpression(partner) ? null : "value"; + if (!numericPartner(lowerer.typeOf(other))) return "value"; + return isString(expr) ? null : "number"; + } + if (RELATIONAL_OPERATORS.has(op)) return isString(other) || isString(expr) ? "value" : "number"; + if (NUMERIC_OPERATORS.has(op)) return "number"; + return NUMERIC_COMPOUNDS.has(op) && parent.right === outer ? "number" : null; +} + +/** A `+` partner whose every value is a number, a boolean, null or + * undefined: `+` adds with it. */ +function numericPartner(type: ts.Type): boolean { + const numeric = + ts.TypeFlags.NumberLike | + ts.TypeFlags.BooleanLike | + ts.TypeFlags.Null | + ts.TypeFlags.Undefined | + ts.TypeFlags.Void; + return (type.flags & ts.TypeFlags.Union) !== 0 + ? constituentTypes(type).every((part) => (part.flags & numeric) !== 0) + : (type.flags & numeric) !== 0; +} + +const EQUALITY_OPERATORS = new Set([ + ts.SyntaxKind.EqualsEqualsEqualsToken, + ts.SyntaxKind.ExclamationEqualsEqualsToken, + ts.SyntaxKind.EqualsEqualsToken, + ts.SyntaxKind.ExclamationEqualsToken, +]); + +const RELATIONAL_OPERATORS = new Set([ + ts.SyntaxKind.LessThanToken, + ts.SyntaxKind.GreaterThanToken, + ts.SyntaxKind.LessThanEqualsToken, + ts.SyntaxKind.GreaterThanEqualsToken, +]); + +const NUMERIC_OPERATORS = new Set([ + ts.SyntaxKind.MinusToken, + ts.SyntaxKind.AsteriskToken, + ts.SyntaxKind.SlashToken, + ts.SyntaxKind.PercentToken, + ts.SyntaxKind.AsteriskAsteriskToken, + ts.SyntaxKind.AmpersandToken, + ts.SyntaxKind.BarToken, + ts.SyntaxKind.CaretToken, + ts.SyntaxKind.LessThanLessThanToken, + ts.SyntaxKind.GreaterThanGreaterThanToken, + ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken, +]); + +const NUMERIC_COMPOUNDS = new Set([ + ts.SyntaxKind.MinusEqualsToken, + ts.SyntaxKind.AsteriskEqualsToken, + ts.SyntaxKind.SlashEqualsToken, + ts.SyntaxKind.PercentEqualsToken, + ts.SyntaxKind.AsteriskAsteriskEqualsToken, + ts.SyntaxKind.AmpersandEqualsToken, + ts.SyntaxKind.BarEqualsToken, + ts.SyntaxKind.CaretEqualsToken, + ts.SyntaxKind.LessThanLessThanEqualsToken, + ts.SyntaxKind.GreaterThanGreaterThanEqualsToken, + ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, +]); + +/** Whether the use of `t[i]!` tells undefined from NaN: a converting use + * that takes the value itself (see convertingUseOf), or a destination that + * holds a missing element (see assertedElementKeepsUndefined) other than a + * return, whose slot has the function's number type. */ +export function assertedReadObservesUndefined( + lowerer: Lowerer, + node: ts.NonNullExpression, +): boolean { + if (convertingUseOf(lowerer, node) === "value") return true; + let outer: ts.Expression = node; + while (ts.isParenthesizedExpression(outer.parent)) outer = outer.parent; + const parent = outer.parent; + if (ts.isReturnStatement(parent) || (ts.isArrowFunction(parent) && parent.body === outer)) + return false; + return assertedElementKeepsUndefined(lowerer, node); +} + export function runtimeOptionalAssertionErases( lowerer: Lowerer, expr: ts.Expression, diff --git a/packages/compiler/src/frontend/lowering/lower-inspect.ts b/packages/compiler/src/frontend/lowering/lower-inspect.ts index 7f0f3684a..e7a43bde1 100644 --- a/packages/compiler/src/frontend/lowering/lower-inspect.ts +++ b/packages/compiler/src/frontend/lowering/lower-inspect.ts @@ -736,11 +736,7 @@ function inspectSupport( case "array": return inspectSupport(lowerer, t.elem, visiting, out); case "bytes": - // A Uint8Array and a Buffer share the u8 representation and print - // differently; the other element kinds are never Buffers. - return t.elem === "u8" - ? "Uint8Array and Buffer values inside composites have no inspect lowering yet (Buffer's form vs Uint8Array's is not recorded in the static type here)" - : null; + return null; case "record": { if (visiting.has(t.shapeId)) { out.recursive = true; @@ -861,7 +857,10 @@ function inspectSupport( } // Generator objects print through their checked capsule: Node's // `Object [Generator] {}`, or the tag of the iterator they implement. + // URLs and URLSearchParams print through their handles. case "generator": + case "url": + case "searchParams": return null; default: return `'${lowerer.fmt(t)}' values have no inspect lowering`; @@ -902,6 +901,117 @@ export function inspectExpr( recurse: IrExpr, depth: IrExpr, loc: SrcLoc, +): IrExpr { + const render = inspectExprBody(lowerer, t, value, recurse, depth, loc); + // A top-level render through emitted helpers that can reach a refusal + // (the 'not supported yet' Error of insp.dyn) unwinds the inspector to + // its state before the render on every exit: the Error propagates out of + // the helpers before they close their frames. + if ( + render.kind !== "call" || + recurse.kind !== "numLit" || + recurse.value !== 0 || + !inspectMayRefuse(lowerer, t) + ) + return render; + return withInspectUnwind(lowerer, render, t, loc); +} + +/** A top-level helper render (`call helper(v, r, d)`) through a lifted + * wrapper that takes insp.mark first and runs insp.unwind however the + * render ends: `try { return helper(v, r, d); } finally { insp.unwind(); }`. + * A seqExpr cannot hold the try. */ +function withInspectUnwind( + lowerer: Lowerer, + render: IrExpr & { kind: "call" }, + t: IrType, + loc: SrcLoc, +): IrExpr { + const key = `unwind:${render.callee}`; + let name = lowerer.inspectHelpers.get(key); + if (name === undefined) { + name = keyedHelperName(lowerer, "%util.inspUnwound", key); + lowerer.inspectHelpers.set(key, name); + const params = [ + { localId: "v.0", name: "v", type: t }, + { localId: "r.0", name: "r", type: F64 }, + { localId: "d.0", name: "d", type: F64 }, + ]; + const call = (fn: "insp.mark" | "insp.unwind"): IrStmt => ({ + kind: "exprStmt", + expr: { kind: "libCall", fn, args: [], type: VOID, loc }, + loc, + }); + lowerer.liftedFns.push({ + name, + params, + returnType: STRING, + locals: params.map((p) => ({ id: p.localId, name: p.name, type: p.type, mutable: false })), + body: [ + call("insp.mark"), + { + kind: "tryCatch", + tryBody: [ + { + kind: "return", + value: { + kind: "call", + callee: render.callee, + args: params.map((p) => varRef(p.localId, p.type, loc)), + type: STRING, + loc, + }, + loc, + }, + ], + catchBody: null, + catchLocalId: null, + finallyBody: [call("insp.unwind")], + loc, + }, + ], + loc, + }); + } + return { ...render, callee: name }; +} + +/** Whether inspecting a `t` value can end in an inspection refusal: `t` + * or a type reachable from it is a checked-dynamic value, a generator, a + * Dirent row or a class instance, or a record or array that can keep + * undeclared properties, which can render through a checked-dynamic view. */ +function inspectMayRefuse(lowerer: Lowerer, t: IrType): boolean { + const seen = new Set(); + const walk = (u: IrType): boolean => { + if (u.kind === "dyn" || u.kind === "generator") return true; + if (u.kind === "record") { + const shape = lowerer.shapes.get(u.shapeId); + if (shape && isDirentShape(shape)) return true; + // The kept source properties render through the checked view (the + // helper's source gate). + if (recordMayKeepSource(lowerer, u)) return true; + } + // So do an array's properties besides its elements. + if (u.kind === "array" && lowerer.dynConvertible(u)) return true; + // A class instance can render through its checked-dynamic view, which + // a helper built earlier may only learn at the end of lowering + // (classInspectsAddedProperties). + if (u.kind === "object") return true; + const k = typeKey(u); + if (seen.has(k)) return false; + seen.add(k); + return typeConstituents(lowerer, u).some(walk); + }; + return walk(t); +} + +function inspectExprBody( + lowerer: Lowerer, + t: IrType, + value: IrExpr, + recurse: IrExpr, + depth: IrExpr, + loc: SrcLoc, ): IrExpr { // A Dirent row renders through its dyn view: Node's `Dirent { ... }` // with the Symbol(type) key. @@ -950,9 +1060,29 @@ export function inspectExpr( loc, }; } - return { kind: "libCall", fn: "insp.buffer", args: [value], type: STRING, loc }; + // A Uint8Array, a Buffer and a DataView share the u8 representation + // and print differently: the view's own flags pick. + return { + kind: "libCall", + fn: "insp.bytes", + args: [value, recurse, depth], + type: STRING, + loc, + }; case "dyn": return { kind: "libCall", fn: "insp.dyn", args: [value, recurse, depth], type: STRING, loc }; + // URLs and URLSearchParams render through their checked-dynamic + // handles: Node's `URL { href: ..., hash: ... }` and + // `URLSearchParams { 'a' => '1' }`. + case "url": + case "searchParams": + return { + kind: "libCall", + fn: "insp.dyn", + args: [lowerer.coerceToExpected(value, DYN), recurse, depth], + type: STRING, + loc, + }; case "generator": return { kind: "libCall", @@ -2181,15 +2311,17 @@ export function lowerConsoleInspectArg( ); } if (!isBufferTypeName(tname)) { + // A u8 value the checker types as a Uint8Array may still hold a + // Buffer, which Node prints as one: the view's flags pick. return { kind: "libCall", - fn: "insp.typedArray", + fn: t.elem === "u8" ? "insp.bytes" : "insp.typedArray", args: [value, numLit(0, loc), numLit(2, loc)], type: STRING, loc, }; } - return inspectExpr(lowerer, t, value, numLit(0, loc), numLit(2, loc), loc); + return { kind: "libCall", fn: "insp.buffer", args: [value], type: STRING, loc }; } if (t.kind === "void") { // Node prints "undefined" for a void call's result; a void expression @@ -2358,40 +2490,55 @@ function parseInspectOptions( /** A render under non-default breakLength/compact/sorted: the value is evaluated * first, the layout applies to this render only, and the defaults return - * afterwards. */ + * however the render ends, an inspection refusal included. The render runs + * in a lifted function, `(v) => { insp.layout(...); try { return render(v); } + * finally { insp.layout(80, 3, false); } }`, since a seqExpr cannot hold the + * try; `tag` names the render for the function's key. */ function withInspectLayout( lowerer: Lowerer, options: InspectOptions, value: IrExpr, + tag: string, render: (value: IrExpr) => IrExpr, loc: SrcLoc, ): IrExpr { if (options.breakLength === 80 && options.compact === 3 && !options.sorted) return render(value); - const input = lowerer.declareHiddenLocal("%inspectInput", value.type); - const text = lowerer.declareHiddenLocal("%inspectText", STRING); - const layout = (breakLength: number, compact: number, sorted: boolean): IrStmt => ({ - kind: "exprStmt", - expr: { - kind: "libCall", - fn: "insp.layout", - args: [numLit(breakLength, loc), numLit(compact, loc), boolLit(sorted, loc)], - type: VOID, + const key = `layout:${tag}:${typeKey(value.type)}:${options.breakLength}:${options.compact}:${options.sorted}:${options.depth}`; + let name = lowerer.inspectHelpers.get(key); + if (name === undefined) { + name = keyedHelperName(lowerer, "%util.inspLayout", key); + lowerer.inspectHelpers.set(key, name); + const layout = (breakLength: number, compact: number, sorted: boolean): IrStmt => ({ + kind: "exprStmt", + expr: { + kind: "libCall", + fn: "insp.layout", + args: [numLit(breakLength, loc), numLit(compact, loc), boolLit(sorted, loc)], + type: VOID, + loc, + }, loc, - }, - loc, - }); - return { - kind: "seqExpr", - stmts: [ - { kind: "varDecl", localId: input.id, init: value, loc }, - layout(options.breakLength, options.compact, options.sorted), - { kind: "varDecl", localId: text.id, init: render(varRef(input.id, value.type, loc)), loc }, - layout(80, 3, false), - ], - result: varRef(text.id, STRING, loc), - type: STRING, - loc, - }; + }); + lowerer.liftedFns.push({ + name, + params: [{ localId: "v.0", name: "v", type: value.type }], + returnType: STRING, + locals: [{ id: "v.0", name: "v", type: value.type, mutable: false }], + body: [ + layout(options.breakLength, options.compact, options.sorted), + { + kind: "tryCatch", + tryBody: [{ kind: "return", value: render(varRef("v.0", value.type, loc)), loc }], + catchBody: null, + catchLocalId: null, + finallyBody: [layout(80, 3, false)], + loc, + }, + ], + loc, + }); + } + return { kind: "call", callee: name, args: [value], type: STRING, loc }; } /** `util.inspect(fn)` / `util.inspect(Cls)` over a DIRECT identifier @@ -2524,9 +2671,13 @@ export function lowerInspectValue( lowerer, options, value, + "typedArray", (input) => ({ kind: "libCall", - fn: "insp.typedArray", + fn: + value.type.kind === "bytes" && value.type.elem === "u8" + ? "insp.bytes" + : "insp.typedArray", args: [input, numLit(0, loc), numLit(options.depth, loc)], type: STRING, loc, @@ -2535,7 +2686,7 @@ export function lowerInspectValue( ); } // Buffers render fully at any depth and on one line (custom inspect). - return inspectExpr(lowerer, value.type, value, numLit(0, loc), numLit(2, loc), loc); + return { kind: "libCall", fn: "insp.buffer", args: [value], type: STRING, loc }; } const walk = { recursive: false }; const reason = inspectSupport(lowerer, value.type, new Set(), walk); @@ -2549,6 +2700,7 @@ export function lowerInspectValue( lowerer, options, value, + "dirDyn", (input) => ({ kind: "libCall", fn: "console.dirDyn", @@ -2563,6 +2715,7 @@ export function lowerInspectValue( lowerer, options, value, + "inspect", (input) => inspectExpr(lowerer, value.type, input, numLit(0, loc), numLit(depth, loc), loc), loc, ); @@ -2639,10 +2792,21 @@ function formatSArg(lowerer: Lowerer, node: ts.Expression, depth: number, loc: S } /** %O (depth 2) / %o (showHidden, depth 4) — inspect with the spec's - * option deltas; %o fences over arrays (showHidden adds their hidden - * [length] entry, which has no lowering). */ + * option deltas. A checked-dynamic argument renders through the runtime's + * showHidden walk; static %o fences over arrays and nested dynamic values + * (showHidden adds an array's hidden [length] entry, which the static + * rendering has no lowering for). */ function formatOArg(lowerer: Lowerer, node: ts.Expression, depth: number, loc: SrcLoc): IrExpr { const value = lowerer.lowerExpr(node); + if (depth === 4 && value.type.kind === "dyn") { + return { + kind: "libCall", + fn: "insp.dynHidden", + args: [value, numLit(4, loc)], + type: STRING, + loc, + }; + } if (value.type.kind === "bytes") { lowerer.noLowering( `util.format %${depth === 4 ? "o" : "O"} of typed-array values`, @@ -2658,11 +2822,11 @@ function formatOArg(lowerer: Lowerer, node: ts.Expression, depth: number, loc: S node, reason, ); - if (depth === 4 && typeTreeHasArray(lowerer, value.type, new Set())) { + if (depth === 4 && typeTreeHasHidden(lowerer, value.type, new Set())) { lowerer.noLowering( "util.format %o over arrays", node, - "%o renders with showHidden (arrays gain a hidden [length] entry) — use %O for the default rendering", + "%o renders with showHidden (arrays gain a hidden [length] entry) — use %O for the default rendering, or pass the value as unknown", ); } return inspectExpr(lowerer, value.type, value, numLit(0, loc), numLit(depth, loc), loc); @@ -3063,35 +3227,36 @@ export function lowerFormatCall( } /** Arrays anywhere in the tree — the %o (showHidden) gate. */ -function typeTreeHasArray(lowerer: Lowerer, t: IrType, visiting: Set): boolean { +function typeTreeHasHidden(lowerer: Lowerer, t: IrType, visiting: Set): boolean { switch (t.kind) { case "array": + case "dyn": return true; case "record": { if (visiting.has(t.shapeId)) return false; visiting.add(t.shapeId); const shape = lowerer.shapes.get(t.shapeId); if (shape?.tuple) return true; - return (shape?.fields ?? []).some((f) => typeTreeHasArray(lowerer, f.type, visiting)); + return (shape?.fields ?? []).some((f) => typeTreeHasHidden(lowerer, f.type, visiting)); } case "map": return ( - typeTreeHasArray(lowerer, t.key, visiting) || typeTreeHasArray(lowerer, t.value, visiting) + typeTreeHasHidden(lowerer, t.key, visiting) || typeTreeHasHidden(lowerer, t.value, visiting) ); case "set": - return typeTreeHasArray(lowerer, t.elem, visiting); + return typeTreeHasHidden(lowerer, t.elem, visiting); case "union": { if (visiting.has(t.unionId)) return false; visiting.add(t.unionId); return (lowerer.unions.get(t.unionId)?.arms ?? []).some((a) => - typeTreeHasArray(lowerer, a, visiting), + typeTreeHasHidden(lowerer, a, visiting), ); } case "object": { if (visiting.has(t.className)) return false; visiting.add(t.className); return (lowerer.classes.get(t.className)?.def.fields ?? []).some((f) => - typeTreeHasArray(lowerer, f.type, visiting), + typeTreeHasHidden(lowerer, f.type, visiting), ); } case "bytes": diff --git a/packages/compiler/src/frontend/lowering/lower-modules.ts b/packages/compiler/src/frontend/lowering/lower-modules.ts index 5238333ad..75f18fe37 100644 --- a/packages/compiler/src/frontend/lowering/lower-modules.ts +++ b/packages/compiler/src/frontend/lowering/lower-modules.ts @@ -43,10 +43,14 @@ import { } from "./cycle-initialization.js"; import { markRequireEarlyBindings } from "./require-initialization.js"; import { + cjsHasLiveMemberExports, cjsTableMethodEntry, inlineProgramRequireOf, nestedCjsExportAssignmentsOf, requireNestedPatternsOf, + splitRequireBindingOf, + splitRequireBindingOfIdent, + wholeExportSymbolOfModule, } from "./cjs-inline-require.js"; import { isDeadTscHelperDecl, tscInteropBindingOfDecl } from "./cjs-tsc-interop.js"; import { collectJsonRequires, isJsonRequireDecl } from "./json-require.js"; @@ -1597,14 +1601,26 @@ export function collectGlobals( // require() of a program module is not: the exporter re-exports // that module's exports, which requirers resolve through the // checker's alias (the statement lowers to the dep's %init). + // A split binding re-exported whole with later member writes needs + // a mutable root: `module.exports = m; module.exports.extra = 1` + // extends the SAME object Node exposes. Without later members the + // binder is pure alias plumbing (no storage). + const splitWholeBinding = ts.isIdentifier(rhs) + ? splitRequireBindingOfIdent(lowerer, rhs) + : null; + const hasMemberExports = cjsHasLiveMemberExports(lowerer, sf); + const splitWhole = + splitWholeBinding !== null && + wholeExportSymbolOfModule(lowerer, splitWholeBinding.dep) !== null && + hasMemberExports; const factoryValued = - !ts.isIdentifier(rhs) && + (!ts.isIdentifier(rhs) || splitWhole) && !ts.isClassExpression(rhs) && !ts.isObjectLiteralExpression(rhs) && !( requireSpecOf(rhs) !== null && inlineProgramRequireOf(lowerer, rhs) !== null && - !sf.statements.nodes.some((s) => cjsExportAssignmentOf(s)?.kind === "member") + !hasMemberExports ) && cjsExportTargetLiteral(rhs, sf) === null; if (cjsScalarLiteral(rhs) || fnValued || factoryValued) { @@ -1617,6 +1633,9 @@ export function collectGlobals( // A returned object remains the live CommonJS root; later // exports.member writes must update that same open object. if (factoryValued && t?.kind === "record" && lowerer.dynConvertible(t)) t = DYN; + // A split whole-export root is extended by later member writes; + // keep it checked-dynamic so those writes reach the same object. + if (splitWhole && t && t.kind !== "dyn") t = DYN; if (t && t.kind !== "void") { const g: IrGlobal = { id: `%g.${tag}exports`, @@ -2361,7 +2380,6 @@ export function collectGlobals( // References from separately-declared functions cascade to // their own per-site runtime fences. const factoryType = - !isLet && isJsSourceFile(sf) && !decl.type && !hasJsTypeAnnotation(decl) && @@ -2708,6 +2726,7 @@ function noteVarGlobalEntryInit(lowerer: Lowerer, sf: ts.SourceFile, g: IrGlobal * plumbing (lowerVarDeclarator): no storage, the reads resolve through to * the module. JSON documents and native FFI requires keep their storage. */ function requireAliasDecl(lowerer: Lowerer, decl: ts.VariableDeclaration): boolean { + if (splitRequireBindingOf(lowerer, decl) !== null) return true; return ( decl.initializer !== undefined && requireSpecOf(decl.initializer) !== null && diff --git a/packages/compiler/src/frontend/lowering/lower-stmts.ts b/packages/compiler/src/frontend/lowering/lower-stmts.ts index a19061fde..0657c0e25 100644 --- a/packages/compiler/src/frontend/lowering/lower-stmts.ts +++ b/packages/compiler/src/frontend/lowering/lower-stmts.ts @@ -1,4 +1,11 @@ import { lowerTupleAliasDecl, stripTypeWrappers } from "./typed-arguments.js"; +import { + allBytesArms, + indexedUnionArms, + lowerIndexedUnionMember, + lowerIndexedUnionNumberRead, + lowerIndexedUnionRead, +} from "./indexed-unions.js"; import { declaredMemberOf, isPromisePrototypeRead } from "./expressions/property-access.js"; import { hostsAll } from "./expressions/hosted-narrowing.js"; import { requestGeneralStreamSurface } from "./general-streams.js"; @@ -39,6 +46,11 @@ import { cjsTableMethodEntry, inlineProgramRequireOf, requireNestedPatternsOf, + splitRequireAssignmentOf, + splitRequireBindingOf, + splitRequireBindingOfIdent, + splitRequireEarlyReadOf, + wholeExportSymbolOfModule, } from "./cjs-inline-require.js"; import { cjsExportMemberWriteGlobalOf, @@ -1935,6 +1947,23 @@ function lowerVarDeclarator( isConst: boolean, isLet: boolean, ): IrStmt[] { + // `var m; m = require("./x")`: the declaration is alias plumbing; the + // assignment owns the module's run-once %init (cjs-inline-require.ts). + // A read that code before the assignment can reach keeps Node's hoisted + // `undefined` divergence visible at build time, like a var require + // declaration below runnable code. + const split = splitRequireBindingOf(lowerer, decl); + if (split !== null) { + const early = splitRequireEarlyReadOf(lowerer, split); + if (early !== null) { + lowerer.unsupported( + "SC1013", + early, + `var require() binding '${(decl.name as ts.Identifier).text}' below code that can reach it (Node reads undefined before the require runs, which is not modeled — assign the require above the code that can run first)`, + ); + } + return []; + } // The canonical ESM bridge to a compiled program module. Like a // top-level CommonJS require declaration, the binding is alias // plumbing while the dependency evaluates at this statement's @@ -7538,6 +7567,26 @@ function lowerCjsSingleValueExport( return lowerer.requireInitStmt(req.spec, req.call) ?? { kind: "block", body: [], loc }; } if (ts.isIdentifier(rhs)) { + const split = splitRequireBindingOfIdent(lowerer, rhs); + if (split !== null) { + if (wholeExportSymbolOfModule(lowerer, split.dep) === null) { + lowerer.unsupported( + "SC1090", + rhs, + `the exports object of '${split.spec}' as a value (its exports compile to a static table: read require(${JSON.stringify(split.spec)}).member directly)`, + ); + } + const root = lowerer.globalsByDeclNode.get(expr); + if (root !== undefined) { + return { + kind: "assign", + localId: root.id, + value: lowerer.lowerExprExpecting(rhs, root.type), + loc: locOf(rhs), + }; + } + return { kind: "block", body: [], loc }; + } const sym = lowerer.resolveValueSymbol(rhs); if (!sym) return null; if ( @@ -8448,6 +8497,16 @@ export function lowerExprStatement(lowerer: Lowerer, expr: ts.Expression): IrStm if (!ts.isIdentifier(expr.left)) { lowerer.unsupported("SC1090", expr.left, "assignment to non-variables"); } + const splitAssign = splitRequireAssignmentOf(lowerer, expr); + if (splitAssign !== null) { + return ( + lowerer.requireInitStmt(splitAssign.spec, splitAssign.call) ?? { + kind: "block", + body: [], + loc: locOf(expr), + } + ); + } const target = lowerer.resolveWritable(expr.left); if (!target) lowerer.rejectUnresolved( @@ -10162,13 +10221,8 @@ export function lowerForOf(lowerer: Lowerer, stmt: ts.ForOfStatement): IrStmt { loc: locOf(iterSrc), }; } - if (iterable.type.kind === "bytes") { - return lowerForOfBytes( - lowerer, - stmt, - iterable as IrExpr & { type: IrType & { kind: "bytes" } }, - labels, - ); + if (iterable.type.kind === "bytes" || indexedUnionArms(lowerer, iterable.type)) { + return lowerForOfBytes(lowerer, stmt, iterable, labels); } if (iterable.type.kind !== "array") { // The lib types strings as iterable too, so those for-ofs typecheck; @@ -10726,7 +10780,7 @@ export function lowerForOf(lowerer: Lowerer, stmt: ts.ForOfStatement): IrStmt { function lowerForOfBytes( lowerer: Lowerer, stmt: ts.ForOfStatement, - iterable: IrExpr & { type: IrType & { kind: "bytes" } }, + iterable: IrExpr, labels?: string[], ): IrStmt { const loc = locOf(stmt); @@ -10820,7 +10874,16 @@ function lowerForOfStoredNumericIterator( const loc = locOf(stmt); const sourceT = state.sourceType; - if (!((sourceT.kind === "array" && sourceT.elem.kind === "f64") || sourceT.kind === "bytes")) { + // A union of typed arrays and number arrays (indexed-unions.ts) reads + // through its arms' own length and element reads. + const unionArms = indexedUnionArms(lowerer, sourceT); + if ( + !( + (sourceT.kind === "array" && sourceT.elem.kind === "f64") || + sourceT.kind === "bytes" || + unionArms + ) + ) { throw new InternalCompilerError("internal: retained numeric iterator has a non-numeric source"); } @@ -10828,35 +10891,44 @@ function lowerForOfStoredNumericIterator( const doneRef = (): IrExpr => varRef(state.doneLocalId, BOOL, loc); const sourceRef = (): IrExpr => varRef(state.sourceLocalId, sourceT, loc); const sourceLength = (): IrExpr => - sourceT.kind === "array" - ? { - kind: "arrIntrinsic", - method: "length", - receiver: sourceRef(), - args: [], - type: F64, - loc, - } - : { - kind: "bytesIntrinsic", - method: "length", - receiver: sourceRef(), - args: [], - type: F64, - loc, - }; - const valueT = sourceT.kind === "array" ? arrayValueType(lowerer, F64) : F64; + unionArms + ? lowerIndexedUnionMember(lowerer, sourceRef(), unionArms, "length", loc)! + : sourceT.kind === "array" + ? { + kind: "arrIntrinsic", + method: "length", + receiver: sourceRef(), + args: [], + type: F64, + loc, + } + : { + kind: "bytesIntrinsic", + method: "length", + receiver: sourceRef(), + args: [], + type: F64, + loc, + }; + const valueT = + sourceT.kind === "array" || (unionArms && !allBytesArms(unionArms)) + ? arrayValueType(lowerer, F64) + : F64; const sourceValue = (): IrExpr => - sourceT.kind === "array" - ? arrayValueRead(lowerer, sourceRef(), indexRef(), F64, loc) - : { - kind: "bytesIntrinsic", - method: "get", - receiver: sourceRef(), - args: [indexRef()], - type: F64, - loc, - }; + unionArms + ? allBytesArms(unionArms) + ? lowerIndexedUnionNumberRead(lowerer, sourceRef(), unionArms, indexRef(), loc) + : lowerIndexedUnionRead(lowerer, sourceRef(), unionArms, indexRef(), loc) + : sourceT.kind === "array" + ? arrayValueRead(lowerer, sourceRef(), indexRef(), F64, loc) + : { + kind: "bytesIntrinsic", + method: "get", + receiver: sourceRef(), + args: [indexRef()], + type: F64, + loc, + }; const one: IrExpr = { kind: "numLit", value: 1, type: F64, loc }; lowerer.scopes.push(new Map()); diff --git a/packages/compiler/src/frontend/lowering/lowerer.ts b/packages/compiler/src/frontend/lowering/lowerer.ts index 2dd44bf3e..4bd43d840 100644 --- a/packages/compiler/src/frontend/lowering/lowerer.ts +++ b/packages/compiler/src/frontend/lowering/lowerer.ts @@ -148,9 +148,14 @@ import { } from "./function-context.js"; import type { FrontendServices } from "../services.js"; import { InternalCompilerError } from "../../errors.js"; +import type { FsPathPlan } from "./builtins/fs-paths.js"; import { defaultAfterUndefined, lowerStaticallyUndefinedArgument } from "./optional-arguments.js"; import { type ProtocolDispatch } from "./class-protocol-dispatch.js"; -import { ClassDynamicDispatch, trackClassFieldCreation } from "./class-dynamic-dispatch.js"; +import { + ClassDynamicDispatch, + boxClassInstancesExactly, + trackClassFieldCreation, +} from "./class-dynamic-dispatch.js"; import { guardClassAttributeWrites } from "./class-attributes.js"; import { guardFrozenWrites, markSloppyRecordWrites } from "./frozen-records.js"; import { applyHandleProperties } from "./handle-properties.js"; @@ -344,10 +349,13 @@ import { } from "./lower-modules.js"; import { prepareCjsModuleGraph, usesCjsTopLevelThis } from "./lower-node-module.js"; import { + type SplitRequireBinding, cjsNamespaceModule, cjsWholeExportValueOf, inlineNamespaceRequireOf, inlineProgramRequireOf, + splitRequireBindingOf, + splitWholeExportAliasTargetOf, } from "./cjs-inline-require.js"; import { tscInteropModuleOf } from "./cjs-tsc-interop.js"; import { usesCjsExportsIdentity } from "./cjs-exports-object.js"; @@ -427,6 +435,7 @@ import { collectSignatureInner, lambdaSignature, } from "./call-signatures.js"; +import { dynamicOverloadChoice, guessedOverloadIdentifier } from "./overload-choice.js"; import { implicitAnyParamSymbolsOf, implicitLocalFnNodeOf, @@ -2292,6 +2301,14 @@ export class Lowerer { /** Per CommonJS file using top-level `this`: the global holding the * object that stands for its original exports (lowerCjsTopLevelThis). */ readonly cjsExportsThis = new Map(); + /** `var m; m = require("./x")` alias bindings (cjs-inline-require.ts). + * Null entries cache declarations that keep ordinary storage. */ + readonly cjsSplitRequireBindings = new Map(); + /** Per-module whole-export symbol (cjs-inline-require.ts). Null means the + * module's exports are a table. */ + readonly cjsWholeExportSymbols = new Map(); + /** Per-module live member-export classification (cjs-inline-require.ts). */ + readonly cjsLiveMemberExports = new Map(); /** Inline program-module require calls whose %init the enclosing member * read or member call is already sequencing (cjs-inline-require.ts). */ readonly inlineRequireInitDone = new Set(); @@ -2830,6 +2847,8 @@ export class Lowerer { /** Parameters read as `any` in the error-path copy of an error-first * callback. */ readonly anySymbols = new Set(); + /** overload-choice's answers per call, binding and function. */ + readonly dynamicOverloadAnswers = new Map(); /** Error parameters of an error-first callback with a known value in * the copy being lowered: true while it holds an Error, false while it * holds null (staticCondition folds conditions on them). */ @@ -2905,6 +2924,9 @@ export class Lowerer { /** util.inspect's per-type traversal helpers (%util.insp.N), interned * by typeKey — the assertHelpers pattern with its own namespace. */ readonly inspectHelpers = new Map(); + /** Indexed-union safe-read helpers mapped to their numeric twins, for the + * fusion of an immediate ToNumber (tryLowerNumericIndexRead). */ + readonly indexedUnionNumericTwins = new Map(); private readonly unionLiteralOwners = new Map< string, { owners: Map | null; shapes: number; unions: number } @@ -3146,8 +3168,13 @@ export class Lowerer { * (builtins/fs-paths.ts): each lowers to the hidden local that holds its * value, which is null until the path's lowering has saved it. */ readonly stagedArguments = new Map(); - /** The staged arguments that follow each such URL path, in order. */ - readonly stagedAfterPath = new Map(); + /** What each fs path argument of a URL-path call lowers to (the plans + * of builtins/fs-paths.ts). */ + readonly fsPathPlans = new Map(); + /** The existsSync/fs.promises calls whose converted URL paths are being + * lowered into the call itself (lowerFallibleFsUrlCall). A call may be + * lowered more than once, and each lowering converts again. */ + readonly fallibleFsCalls = new Set(); readonly moduleNsParamOverrides = new Map< ts.ParameterDeclaration, IrType & { kind: "moduleNs" } @@ -4131,6 +4158,11 @@ export class Lowerer { // registry (globals, fn signatures, classes) applies unchanged. const cjsValue = this.cjsExportValueSymbol(symbol); if (cjsValue) symbol = cjsValue; + // `var m; m = require("./x"); module.exports = m` over a whole-export + // target: TS types the wrapper's export= as `any`, so reconnect it to + // the target's value symbol explicitly. + const splitAlias = splitWholeExportAliasTargetOf(this, symbol); + if (splitAlias) symbol = splitAlias; this.flushDeferred(symbol); return symbol; } @@ -4524,8 +4556,8 @@ export class Lowerer { const decl = decls.find(ts.isImportClause) ?? decls[0]; if (!decl) return null; if (ts.isImportClause(decl)) return this.cjsDefaultImportDepOf(decl); - if (!ts.isVariableDeclaration(decl) || !ts.isIdentifier(decl.name) || !decl.initializer) - return null; + if (!ts.isVariableDeclaration(decl) || !ts.isIdentifier(decl.name)) return null; + if (decl.initializer === undefined) return splitRequireBindingOf(this, decl)?.dep ?? null; { const interop = tscInteropModuleOf(this, expr); if (interop !== null) return cjsNamespaceModule(this, interop.dep) ? interop.dep : null; @@ -4630,6 +4662,9 @@ export class Lowerer { // a binding (cjs-inline-require.ts sequences the module's %init). if (!ts.isIdentifier(expr)) return this.cjsModuleRefDepOf(expr) !== null; const sym = this.checker.getSymbolAtLocation(expr); + const splitDecl = sym?.declarations.find(ts.isVariableDeclaration); + const split = splitDecl === undefined ? null : splitRequireBindingOf(this, splitDecl); + if (split !== null) return cjsNamespaceModule(this, split.dep); if (this.localModuleBindingDepOf(expr) === null) return false; if (this.createRequireWholeExportSymbolOf(expr) !== null) return false; // SINGLE-VALUE exporters (`module.exports = Countdown` / `= double` / @@ -4937,6 +4972,13 @@ export class Lowerer { * their external dependencies by name). Null for everything else * (builtins load nothing; the rest kept its preflight fence). */ requireInitStmt(spec: string, node: ts.Node): IrStmt | null { + if (this.inlineRequireCycleCalls.has(node)) { + this.unsupported( + "SC1090", + node, + `require() of '${spec}' while it is still evaluating (a require cycle: Node answers its partial exports, which the static export table does not model)`, + ); + } if (canonicalBuiltinModule(spec) === "punycode") return this.punycodeRequireWarning(node); // Project requires resolve within the program; another bare require can // be a program-module edge when it names an opted-in --npm-static package @@ -6447,6 +6489,22 @@ export class Lowerer { }); return keys; }; + // `t[i]!` on a typed array, stored into an array, keeps an invalid + // index's undefined (assertedReadObservesUndefined): `!` performs no + // runtime check. A read whose consumers treat undefined like NaN stores + // NaN instead. + const assertedReadMayBeUndefined = (node: ts.Expression): boolean => { + let e = node; + while (ts.isParenthesizedExpression(e)) e = e.expression; + if (!ts.isNonNullExpression(e)) return false; + let read = e.expression; + while (ts.isParenthesizedExpression(read)) read = read.expression; + return ( + ts.isElementAccessExpression(read) && + this.mapTypeOf(this.typeOf(read.expression))?.kind === "bytes" && + !nanCoded.isNumericRead(read) + ); + }; const elementStates = new ArrayElementStates({ elementAdmitsUndefined: (key) => { siteDependencies?.read(key); @@ -6456,7 +6514,7 @@ export class Lowerer { allocationOwner: (node) => ownership.allocationOwner(node), arrayKeys: arrayKeysOf, mayBeUndefined: (node) => { - if (explicitlyNonNull(node)) return false; + if (explicitlyNonNull(node)) return assertedReadMayBeUndefined(node); if (mayBeOptional(node)) return true; // `undefined as unknown as T` keeps the undefined value. for ( @@ -7733,6 +7791,7 @@ export class Lowerer { finalizeClassMethodValues(this, functions); finalizePrivateBrands(this, functions); trackClassFieldCreation(this, functions); + boxClassInstancesExactly(this, functions); guardClassAttributeWrites(this, functions); guardFrozenWrites(this, functions); applyHandleProperties(this, functions); @@ -8999,6 +9058,20 @@ export class Lowerer { typeOf(node: ts.Node): ts.Type { if (this.anySymbols.size > 0 && this.readsAnySymbol(node)) return this.checker.getAnyType(); + // A checked-dynamic argument that another overload could take at run + // time leaves the resolved overload's return a guess, and JS bindings + // initialized with that result hold whatever it was. + if ( + (ts.isCallExpression(node) || ts.isNewExpression(node)) && + dynamicOverloadChoice(this, node) + ) + return this.checker.getAnyType(); + if ( + ts.isIdentifier(node) && + isJsSourceFile(ts.getSourceFileOfNode(node)) && + guessedOverloadIdentifier(this, node) + ) + return this.checker.getAnyType(); if (ts.isPropertyAccessExpression(node) && isJsSourceFile(ts.getSourceFileOfNode(node))) { const receiver = node.expression.kind === ts.SyntaxKind.ThisKeyword && this.fnStack.length > 0 diff --git a/packages/compiler/src/frontend/lowering/object-factory-new.ts b/packages/compiler/src/frontend/lowering/object-factory-new.ts index bcb675692..c672f82e2 100644 --- a/packages/compiler/src/frontend/lowering/object-factory-new.ts +++ b/packages/compiler/src/frontend/lowering/object-factory-new.ts @@ -6,10 +6,14 @@ import { bindingNeverReassigned } from "./binding-analysis.js"; import { implicitDefaultInstance } from "./generic-functions.js"; import { type FnSig } from "./call-signatures.js"; -/** An ordinary constructor's explicit object return replaces its receiver. - * Without observing this or new.target, it can use the function's call ABI. */ -function isObjectFactoryNew(lowerer: Lowerer, expr: ts.NewExpression): boolean { - if (!ts.isIdentifier(expr.expression) || lowerer.peekLocal(expr.expression)) return false; +/** The JavaScript function declaration (or never-reassigned function + * expression binding) `new` calls, when it is an ordinary constructor: not + * a generator or async function. */ +function jsConstructorFunctionOf( + lowerer: Lowerer, + expr: ts.NewExpression, +): ts.FunctionDeclaration | ts.FunctionExpression | null { + if (!ts.isIdentifier(expr.expression) || lowerer.peekLocal(expr.expression)) return null; // This probe also sees ordinary classes during global collection. Leave // their deferred diagnostics for the class declaration's lowering. const wasCollecting = lowerer.collecting; @@ -20,7 +24,7 @@ function isObjectFactoryNew(lowerer: Lowerer, expr: ts.NewExpression): boolean { } finally { lowerer.collecting = wasCollecting; } - if (!symbol) return false; + if (!symbol) return null; const owner = symbol.declarations.find( (node) => (ts.isFunctionDeclaration(node) && node.body !== undefined) || @@ -45,7 +49,15 @@ function isObjectFactoryNew(lowerer: Lowerer, expr: ts.NewExpression): boolean { declaration.asteriskToken || declaration.modifiers?.nodes.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) ) - return false; + return null; + return declaration; +} + +/** An ordinary constructor's explicit object return replaces its receiver. + * Without observing this or new.target, it can use the function's call ABI. */ +function isObjectFactoryNew(lowerer: Lowerer, expr: ts.NewExpression): boolean { + const declaration = jsConstructorFunctionOf(lowerer, expr); + if (!declaration?.body) return false; const objectReturn = (expression: ts.Expression): boolean => ts.isObjectLiteralExpression(expression) || ts.isArrayLiteralExpression(expression) || @@ -81,8 +93,13 @@ function isObjectFactoryNew(lowerer: Lowerer, expr: ts.NewExpression): boolean { /** Collection must register the shared result before reaching factory * bodies: those bodies can reference later globals in the same module. */ +/** The storage of a JavaScript module binding initialized with `new` of an + * ordinary function: a factory's result and a constructor function's + * receiver (`const head = new Segment()`) are both checked-dynamic + * values, which functions declared elsewhere in the module read through + * the global. */ export function objectFactoryGlobalType(lowerer: Lowerer, expr: ts.NewExpression): IrType | null { - return isObjectFactoryNew(lowerer, expr) ? DYN : null; + return jsConstructorFunctionOf(lowerer, expr) !== null ? DYN : null; } export function objectFactorySignature(lowerer: Lowerer, expr: ts.NewExpression): FnSig | null { diff --git a/packages/compiler/src/frontend/lowering/overload-choice.ts b/packages/compiler/src/frontend/lowering/overload-choice.ts new file mode 100644 index 000000000..f973ccf2e --- /dev/null +++ b/packages/compiler/src/frontend/lowering/overload-choice.ts @@ -0,0 +1,197 @@ +import * as ts from "../ts7/adapter.js"; +import type { Lowerer } from "./lowerer.js"; +import { typeEquals, type IrType } from "../../ir/ir.js"; +import { isJsSourceFile } from "../program.js"; +import { isThisParameter } from "./call-signatures.js"; +import { hasExplicitJsDocReturn } from "./function-returns.js"; +import { hasJsTypeAnnotation } from "./lower-stmts.js"; + +/** Whether a checked-dynamic argument leaves a JS call's overload + * undecided. + * + * The checker resolves an overloaded call whose argument is `any` (an + * untyped parameter, a value read from one) to the FIRST overload that + * argument satisfies, but the value can match any overload at run time: + * `generateKeyPairSync("ec", options)` answers KeyObjects or encoded + * strings by the options' contents, `digest(encoding)` a Buffer when the + * encoding is undefined. When another overload the call could take at + * run time returns a different type, the resolved overload's return is a + * guess, and the result is checked-dynamic instead. + * + * An overload is reachable when the arguments fit its arity (trailing + * checked-dynamic or `undefined` arguments may be absent) and every + * statically typed argument is assignable to its parameter. Generic + * overloads whose return cannot be mapped without instantiation do not + * count, so the resolved instantiation stands for them. */ +export function dynamicOverloadChoice( + lowerer: Lowerer, + expr: ts.CallExpression | ts.NewExpression, +): boolean { + return cachedAnswer(lowerer, expr, () => computeDynamicOverloadChoice(lowerer, expr)); +} + +/** Whether a JavaScript value's checker type rests on an undecided + * overload (dynamicOverloadChoice): the call itself, an awaited one, a + * call to an unannotated JS function returning such a value, or a read of + * an unannotated JS binding initialized with one (destructured or not). + * Such a value is checked-dynamic wherever the checker's inference would + * otherwise carry the guess into a binding or a return. */ +export function guessedOverloadValue(lowerer: Lowerer, expr: ts.Expression): boolean { + while (ts.isParenthesizedExpression(expr) || ts.isAwaitExpression(expr)) expr = expr.expression; + if (ts.isCallExpression(expr) || ts.isNewExpression(expr)) { + if (!isJsSourceFile(ts.getSourceFileOfNode(expr))) return false; + if (dynamicOverloadChoice(lowerer, expr)) return true; + const decl = lowerer.checker.getResolvedSignature(expr)?.declaration; + return ( + decl !== undefined && + (ts.isFunctionDeclaration(decl) || + ts.isFunctionExpression(decl) || + ts.isArrowFunction(decl)) && + isJsSourceFile(ts.getSourceFileOfNode(decl)) && + returnsGuessedOverloadValue(lowerer, decl) + ); + } + return ts.isIdentifier(expr) && guessedOverloadIdentifier(lowerer, expr); +} + +/** Whether a JS identifier, as a binding's declared name or as a read, + * names a guessedOverloadBinding. */ +export function guessedOverloadIdentifier(lowerer: Lowerer, node: ts.Identifier): boolean { + return cachedAnswer(lowerer, node, () => { + const parent = node.parent; + if ( + parent !== undefined && + (ts.isVariableDeclaration(parent) || ts.isBindingElement(parent)) && + parent.name === node + ) + return guessedOverloadBinding(lowerer, parent); + const decl = lowerer.checker.getSymbolAtLocation(node)?.valueDeclaration; + return decl !== undefined && guessedOverloadBinding(lowerer, decl); + }); +} + +/** Whether `decl` is an unannotated JS variable or destructured binding + * whose declaration's initializer is a guessedOverloadValue. */ +function guessedOverloadBinding(lowerer: Lowerer, decl: ts.Node): boolean { + let root: ts.Node | undefined = decl; + while (root && ts.isBindingElement(root) && root.parent && ts.isBindingPattern(root.parent)) { + root = root.parent.parent; + } + if (!root) return false; + if (!ts.isVariableDeclaration(root) || !root.initializer || root.type) return false; + if (!isJsSourceFile(ts.getSourceFileOfNode(root)) || hasJsTypeAnnotation(root)) return false; + const init = root.initializer; + return cachedAnswer(lowerer, root, () => guessedOverloadValue(lowerer, init)); +} + +/** Whether a return of the unannotated JS function `decl` itself is a + * guessedOverloadValue. */ +export function returnsGuessedOverloadValue( + lowerer: Lowerer, + decl: ts.SignatureDeclaration, +): boolean { + if (decl.type || decl.asteriskToken || hasExplicitJsDocReturn(decl)) return false; + return cachedAnswer(lowerer, decl, () => { + if (ts.isArrowFunction(decl) && decl.body && !ts.isBlock(decl.body)) { + return guessedOverloadValue(lowerer, decl.body); + } + let found = false; + const scan = (node: ts.Node): void => { + if (found || (node !== decl && ts.isFunctionLike(node))) return; + if (ts.isReturnStatement(node) && node.expression) { + found = guessedOverloadValue(lowerer, node.expression); + } + ts.forEachChild(node, scan); + }; + scan(decl); + return found; + }); +} + +/** One answer per node; a node asked again while its answer is being + * computed (recursive functions, self-referencing bindings) answers + * false. */ +function cachedAnswer(lowerer: Lowerer, node: ts.Node, compute: () => boolean): boolean { + const cached = lowerer.dynamicOverloadAnswers.get(node); + if (cached !== undefined) return cached; + lowerer.dynamicOverloadAnswers.set(node, false); + const answer = compute(); + lowerer.dynamicOverloadAnswers.set(node, answer); + return answer; +} + +function computeDynamicOverloadChoice( + lowerer: Lowerer, + expr: ts.CallExpression | ts.NewExpression, +): boolean { + // TypeScript sources keep the resolved overload: their reads validate + // the value against it where it is used. + if (!isJsSourceFile(ts.getSourceFileOfNode(expr))) return false; + const args = expr.arguments?.nodes ?? []; + if (args.length === 0 || args.some(ts.isSpreadElement)) return false; + const dynamic = args.map((arg) => checkedDynamicArgument(lowerer, arg)); + if (!dynamic.includes(true)) return false; + const checker = lowerer.checker; + const calleeType = checker.getTypeAtLocation(expr.expression); + const signatures = ts.isNewExpression(expr) + ? checker.getConstructSignatures(calleeType) + : checker.getCallSignatures(calleeType); + if (signatures.length < 2) return false; + const resolved = checker.getResolvedSignature(expr); + if (!resolved) return false; + const resolvedReturn = lowerer.mapTypeOf(checker.getReturnTypeOfSignature(resolved)); + if (resolvedReturn === null) return false; + // Arguments that may be absent at run time: the trailing run of + // checked-dynamic and `undefined` arguments. + let present = args.length; + while (present > 0 && (dynamic[present - 1] || isUndefinedArgument(args[present - 1]!))) { + present--; + } + for (const signature of signatures) { + const decl = signature.declaration; + if (!decl || decl === resolved.declaration || !ts.isFunctionLike(decl)) continue; + const generic = signature.getTypeParameters().length > 0; + const params = decl.parameters.nodes.filter((param) => !isThisParameter(param)); + const required = params.filter( + (param) => !param.questionToken && !param.initializer && !param.dotDotDotToken, + ).length; + const maximum = params.some((param) => param.dotDotDotToken) ? Infinity : params.length; + if (required > args.length || present > maximum) continue; + const symbols = signature.getParameters(); + let fits = true; + for (let i = 0; i < args.length && i < params.length && fits; i++) { + if (dynamic[i] || generic || params[i]!.dotDotDotToken) continue; + const symbol = symbols[i]; + if (!symbol) continue; + fits = checker.isTypeAssignableTo( + checker.getTypeAtLocation(args[i]!), + checker.getTypeOfSymbol(symbol), + ); + } + if (!fits) continue; + const candidate = lowerer.mapTypeOf(checker.getReturnTypeOfSignature(signature)); + if (candidate !== null && !holdsResult(resolvedReturn, candidate)) return true; + } + return false; +} + +/** Whether a value of the resolved overload's mapped return also holds + * every value of `candidate`: the same type, or a checked-dynamic one (a + * promise of one fulfills with anything). */ +function holdsResult(resolved: IrType, candidate: IrType): boolean { + if (resolved.kind === "dyn" || typeEquals(resolved, candidate)) return true; + return ( + resolved.kind === "promise" && + candidate.kind === "promise" && + holdsResult(resolved.inner, candidate.inner) + ); +} + +function checkedDynamicArgument(lowerer: Lowerer, arg: ts.Expression): boolean { + if (lowerer.checker.getTypeAtLocation(arg).flags & ts.TypeFlags.Any) return true; + return (lowerer.typeOf(arg).flags & ts.TypeFlags.Any) !== 0; +} + +function isUndefinedArgument(arg: ts.Expression): boolean { + return (ts.isIdentifier(arg) && arg.text === "undefined") || ts.isVoidExpression(arg); +} diff --git a/packages/compiler/src/frontend/lowering/surfaces.ts b/packages/compiler/src/frontend/lowering/surfaces.ts index ebf09f9e6..90acabce6 100644 --- a/packages/compiler/src/frontend/lowering/surfaces.ts +++ b/packages/compiler/src/frontend/lowering/surfaces.ts @@ -1635,6 +1635,12 @@ export const BUILTIN_MODULE_FNS: Record< unzip: { fn: "zlib.unzipCb", params: [], result: VOID }, unzipSync: { fn: "zlib.unzipSync", params: [BYTES_U8], result: BYTES_U8 }, crc32: { fn: "zlib.crc32", params: [], result: F64 }, + // Brotli (special-cased in lowerZlibModuleCall): every form takes the + // options entries with Node's BROTLI_ENCODE or BROTLI_DECODE mode. + brotliCompress: { fn: "zlib.cbOpts", params: [], result: VOID }, + brotliCompressSync: { fn: "zlib.syncOpts", params: [], result: BYTES_U8 }, + brotliDecompress: { fn: "zlib.cbOpts", params: [], result: VOID }, + brotliDecompressSync: { fn: "zlib.syncOpts", params: [], result: BYTES_U8 }, // The stream factories (special-cased in lowerZlibModuleCall): each // answers a runtime Transform stream over the zlib engine. createDeflate: { fn: "zlib.streamNew", params: [], result: ZLIB_STREAM }, @@ -1644,6 +1650,8 @@ export const BUILTIN_MODULE_FNS: Record< createDeflateRaw: { fn: "zlib.streamNew", params: [], result: ZLIB_STREAM }, createInflateRaw: { fn: "zlib.streamNew", params: [], result: ZLIB_STREAM }, createUnzip: { fn: "zlib.streamNew", params: [], result: ZLIB_STREAM }, + createBrotliCompress: { fn: "zlib.streamNew", params: [], result: ZLIB_STREAM }, + createBrotliDecompress: { fn: "zlib.streamNew", params: [], result: ZLIB_STREAM }, }, url: { fileURLToPath: { @@ -1681,6 +1689,7 @@ export const BUILTIN_MODULE_FNS: Record< resolve: { fn: "url.legacyResolve", params: [DYN, DYN], result: STRING }, domainToASCII: { fn: "url.domainToASCII", params: [DYN], result: STRING }, domainToUnicode: { fn: "url.domainToUnicode", params: [DYN], result: STRING }, + urlToHttpOptions: { fn: "url.toHttpOptions", params: [DYN], result: DYN }, }, child_process: { // spawnSync's and spawn's call completions are entirely special-cased @@ -2085,7 +2094,16 @@ export const BUILTIN_MODULE_FN_ALIASES: Record< "fs.readFdEncoded", "fs.readFdSync", "fs.readFdSyncBytes", + // The runtime encoding's check before a URL path converts + // (fs-paths.ts). + "fs.checkReadEncoding", ], + // The string source's check before a URL destination converts + // (fs-paths.ts). + copyFileSync: ["fs.checkPath"], + renameSync: ["fs.checkPath"], + copyFile: ["fs.checkPath"], + rename: ["fs.checkPath"], readlinkSync: ["fs.readlinkSyncStr", "fs.readlinkSyncBuffer"], // The bytes-data form and the { mode } options form. writeFileSync: ["fs.writeFileSyncBytes", "fs.writeFileModeSync"], @@ -3048,17 +3066,6 @@ export function builtinModulesArrayLit(loc: { file: string; start: number; end: }; } -/** Member-specific hints for RECOGNIZED builtin modules whose member has - * no lowering. The default-options one-shot zlib/deflate-raw/gzip codecs - * lower for strings and Buffers; the remaining surface points at them. */ -const ZLIB_HINT = - "the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, " + - "and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface"; -/** Brotli has no codec in the static runtime (zlib is the only vendored - * compression library). */ -const BROTLI_HINT = - "Brotli needs a Brotli codec, which the static runtime does not vendor — " + ZLIB_HINT; - const ASSERT_MODULE_HINTS: Record = { ifError: "test explicitly instead: assert.strictEqual(err, null) / " + @@ -3120,16 +3127,6 @@ export const BUILTIN_MODULE_FENCE_HINTS: Record< "a compiled binary has no FIPS provider to enable, and Node itself throws on setFips(true) " + "in a non-FIPS build — getFips() answers 0 here", }, - zlib: { - brotliCompressSync: BROTLI_HINT, - brotliDecompressSync: BROTLI_HINT, - brotliCompress: BROTLI_HINT, - brotliDecompress: BROTLI_HINT, - createBrotliCompress: BROTLI_HINT, - createBrotliDecompress: BROTLI_HINT, - BrotliCompress: BROTLI_HINT, - BrotliDecompress: BROTLI_HINT, - }, http2: { connect: "HTTP/2 client sessions have no lowering — the lowered http2 surface is the SERVER side: " + diff --git a/packages/compiler/src/frontend/pipeline.ts b/packages/compiler/src/frontend/pipeline.ts index 6da81dfbc..c2f528b25 100644 --- a/packages/compiler/src/frontend/pipeline.ts +++ b/packages/compiler/src/frontend/pipeline.ts @@ -228,7 +228,8 @@ function detectAutoPackages( } else if (mode === "lib" && !viaTransitive) { // CJS packages spell their dep edges as top-level requires; the // import-statement scan alone would miss every one of them. - for (const req of requiresOf(stmt)) edges.push({ spec: req.spec, loc: locOf(req.node) }); + for (const req of requiresOf(stmt, load.program)) + edges.push({ spec: req.spec, loc: locOf(req.node) }); } } // Transitive selection counts every literal require() and import() diff --git a/packages/compiler/src/frontend/program-analysis.ts b/packages/compiler/src/frontend/program-analysis.ts index e49b9307e..d4ec9fa98 100644 --- a/packages/compiler/src/frontend/program-analysis.ts +++ b/packages/compiler/src/frontend/program-analysis.ts @@ -1,4 +1,5 @@ import type { + CallExpression, ExportDeclaration, Identifier, SourceFile, @@ -30,6 +31,13 @@ export class ProgramAnalysis { readonly requireEarlyReferences = new Map(); /** Per file: the first top-level statement that can run user code. */ readonly requireFirstRunnable = new Map(); + /** Per file: split require bindings (`var m; m = require("./x")`), from + * declaration to the require call of their one assignment + * (splitRequireBindings7). */ + readonly splitRequireBindings = new Map< + SourceFile, + ReadonlyMap + >(); clear(): void { this.createRequireReasons.clear(); @@ -41,5 +49,6 @@ export class ProgramAnalysis { this.moduleEarlyBindings = null; this.requireEarlyReferences.clear(); this.requireFirstRunnable.clear(); + this.splitRequireBindings.clear(); } } diff --git a/packages/compiler/src/frontend/program.ts b/packages/compiler/src/frontend/program.ts index c5b72d98f..8075379b8 100644 --- a/packages/compiler/src/frontend/program.ts +++ b/packages/compiler/src/frontend/program.ts @@ -1423,17 +1423,31 @@ function isRequireStatement7(stmt: ts.Statement): boolean { ); } +/** A require() occurrence of a top-level statement. `split` marks the + * assignment of a split require binding (splitRequireBindings7): `node` + * is its require call and `decl` the binding's declaration. */ +interface RequireOccurrence7 { + spec: string; + node: ts.Node; + decl: ts.VariableDeclaration | null; + split?: true; +} + /** The require() occurrences of one top-level statement: the declaration - * forms and the bare side-effect call. Empty for everything else. */ -function requiresOf7( - stmt: ts.Statement, -): { spec: string; node: ts.Node; decl: ts.VariableDeclaration | null }[] { + * forms, the bare side-effect call, and the assignment of a split require + * binding. Empty for everything else. */ +function requiresOf7(stmt: ts.Statement, program: ts.Program): RequireOccurrence7[] { if (ts.isExpressionStatement(stmt)) { + const split = splitRequireOfStatement7(program, stmt); + if (split !== null) + return [ + { spec: requireSpecOf7(split.call)!, node: split.call, decl: split.decl, split: true }, + ]; const spec = requireSpecOf7(stmt.expression); return spec !== null ? [{ spec, node: stmt.expression, decl: null }] : []; } if (!ts.isVariableStatement(stmt)) return []; - const out: { spec: string; node: ts.Node; decl: ts.VariableDeclaration | null }[] = []; + const out: RequireOccurrence7[] = []; for (const decl of stmt.declarationList.declarations.nodes) { const spec = decl.initializer !== undefined ? requireSpecOf7(decl.initializer) : null; if (spec !== null) out.push({ spec, node: decl, decl }); @@ -1441,6 +1455,172 @@ function requiresOf7( return out; } +/** CommonJS require bindings split into a declaration and one later + * assignment (`var m; m = require("./x")`): a top-level `var` or `let` + * declaration without initializer in a CommonJS file, assigned by exactly one + * top-level `m = require("")` statement of the require global over + * a compiled program module, and written nowhere else. The binding holds the + * module's exports from the assignment on, as `const m = require("./x")` + * does, so preflight treats the assignment as that require: its module edge, + * its cycle admission and its early-read fence. The lowering's recognizer + * (splitRequireBindingOf in cjs-inline-require.ts) accepts only these + * bindings. Keyed by declaration, with the assignment's require call. */ +function splitRequireBindings7( + program: ts.Program, + sf: ts.SourceFile, +): ReadonlyMap { + const memo = program.analysis.splitRequireBindings; + const cached = memo.get(sf); + if (cached !== undefined) return cached; + const out = new Map(); + memo.set(sf, out); + if (sf.isDeclarationFile || !isCjsJsFile7(sf, program) || !sf.text.includes("require")) + return out; + const checker = program.getTypeChecker(); + const stmts = sf.statements.nodes; + const candidates = new Map< + ts.Symbol, + { decl: ts.VariableDeclaration; call: ts.CallExpression | null; assigns: number } + >(); + for (const stmt of stmts) { + if (!ts.isVariableStatement(stmt)) continue; + if ((stmt.declarationList.flags & (ts.NodeFlags.Const | ts.NodeFlags.Using)) !== 0) continue; + for (const decl of stmt.declarationList.declarations.nodes) { + if (!ts.isIdentifier(decl.name) || decl.initializer !== undefined) continue; + const symbol = checker.getSymbolAtLocation(decl.name); + if (symbol === undefined || symbol.declarations.length !== 1) continue; + candidates.set(symbol, { decl, call: null, assigns: 0 }); + } + } + if (candidates.size === 0) return out; + // The one top-level `m = ...` statement, whose right side is the require. + for (const stmt of stmts) { + if (!ts.isExpressionStatement(stmt) || !ts.isBinaryExpression(stmt.expression)) continue; + const assign = stmt.expression; + if (assign.operatorToken.kind !== ts.SyntaxKind.EqualsToken || !ts.isIdentifier(assign.left)) + continue; + const symbol = checker.getSymbolAtLocation(assign.left); + const candidate = symbol !== undefined ? candidates.get(symbol) : undefined; + if (candidate === undefined) continue; + candidate.assigns++; + let right = assign.right; + while (ts.isParenthesizedExpression(right)) right = right.expression; + if (ts.isCallExpression(right) && splitRequireTarget7(program, sf, right)) + candidate.call = right; + } + const names = new Set(); + for (const candidate of candidates.values()) { + if (candidate.assigns === 1 && candidate.call !== null) + names.add((candidate.decl.name as ts.Identifier).text); + } + if (names.size === 0) return out; + // Exactly one write in the whole file: the assignment itself. + const writes = new Map(); + ts.walkPreorder(sf, (node) => { + if (!ts.isIdentifier(node) || !names.has(node.text)) return undefined; + const parent = node.parent; + const symbol = + parent !== undefined && ts.isShorthandPropertyAssignment(parent) && parent.name === node + ? (checker.getShorthandAssignmentValueSymbol(parent) ?? checker.getSymbolAtLocation(node)) + : checker.getSymbolAtLocation(node); + if (symbol === undefined || !candidates.has(symbol) || !isWriteReference7(node)) + return undefined; + writes.set(symbol, (writes.get(symbol) ?? 0) + 1); + return undefined; + }); + for (const [symbol, candidate] of candidates) { + if (candidate.assigns === 1 && candidate.call !== null && writes.get(symbol) === 1) + out.set(candidate.decl, candidate.call); + } + return out; +} + +/** True when `call` is a require of the CommonJS global over a compiled + * program module: not a builtin, a JSON document or a declaration file. */ +function splitRequireTarget7( + program: ts.Program, + sf: ts.SourceFile, + call: ts.CallExpression, +): boolean { + const spec = requireSpecOf7(call); + if (spec === null || canonicalBuiltinModule(spec) !== null) return false; + if (requireCallBindingKind7(program, call) !== "ambient") return false; + const dep = + resolveImport7(program, sf, spec, "require") ?? npmStaticDepSf7(program, sf, spec, "require"); + return dep !== null && !dep.isDeclarationFile && !dep.fileName.endsWith(".json"); +} + +/** The split require binding a top-level statement assigns, or null. */ +function splitRequireOfStatement7( + program: ts.Program, + stmt: ts.Statement, +): { decl: ts.VariableDeclaration; call: ts.CallExpression } | null { + if ( + !ts.isExpressionStatement(stmt) || + !ts.isBinaryExpression(stmt.expression) || + !ts.isSourceFile(stmt.parent) + ) + return null; + let right = stmt.expression.right; + while (ts.isParenthesizedExpression(right)) right = right.expression; + for (const [decl, call] of splitRequireBindings7(program, stmt.parent)) + if (call === right) return { decl, call }; + return null; +} + +/** The top-level statement of a split require binding's assignment, from + * its require call (`m = require("./x")` or `m = (require("./x"))`). */ +function splitRequireStatementOf7(call: ts.CallExpression): ts.Node | undefined { + let node: ts.Node = call; + while (node.parent !== undefined && ts.isParenthesizedExpression(node.parent)) node = node.parent; + return node.parent?.parent; +} + +/** The require call of a split require binding's declaration, or null. */ +function splitRequireCallOf7( + program: ts.Program, + decl: ts.VariableDeclaration, +): ts.CallExpression | null { + return splitRequireBindings7(program, ts.getSourceFileOfNode(decl)).get(decl) ?? null; +} + +/** True when `id` is written: an assignment target (compound and + * destructuring included), an update operand, or a for-in/of target. */ +function isWriteReference7(id: ts.Identifier): boolean { + let n: ts.Node = id; + for (;;) { + const p: ts.Node | undefined = n.parent; + if (p === undefined) return false; + if (ts.isBinaryExpression(p)) { + const k = p.operatorToken.kind; + return ( + p.left === n && k >= ts.SyntaxKind.FirstAssignment && k <= ts.SyntaxKind.LastAssignment + ); + } + if (ts.isPostfixUnaryExpression(p) || ts.isPrefixUnaryExpression(p)) { + return ( + (p.operator === ts.SyntaxKind.PlusPlusToken || + p.operator === ts.SyntaxKind.MinusMinusToken) && + p.operand === n + ); + } + if (ts.isForOfStatement(p) || ts.isForInStatement(p)) return p.initializer === n; + if ( + ts.isParenthesizedExpression(p) || + ts.isArrayLiteralExpression(p) || + ts.isSpreadElement(p) || + ts.isSpreadAssignment(p) || + ts.isShorthandPropertyAssignment(p) || + ts.isObjectLiteralExpression(p) || + (ts.isPropertyAssignment(p) && p.initializer === n) + ) { + n = p; + continue; + } + return false; + } +} + /** `true`, or `!0`, its minified spelling. */ function isTrueLiteral(expr: ts.Expression): boolean { return ( @@ -1580,7 +1760,7 @@ function purePrefixDecl7(decl: ts.VariableDeclaration): boolean { function purePrefixStmt7(program: ts.Program, s: ts.Statement): boolean { if (ts.isEmptyStatement(s) || ts.isFunctionDeclaration(s)) return true; if (ts.isExpressionStatement(s) && ts.isStringLiteral(s.expression)) return true; // directive - if (isRequireStatement7(s)) return true; + if (isRequireStatement7(s) || splitRequireOfStatement7(program, s) !== null) return true; if (isCjsJsFile7(ts.getSourceFileOfNode(s), program)) { if (ts.isExpressionStatement(s) && isEsModuleStamp(s.expression)) { const call = s.expression as ts.CallExpression; @@ -1707,12 +1887,20 @@ function requireEarlyReference7( const cached = memo.get(decl); if (cached !== undefined) return cached; let found: ts.Identifier | null = null; - const stmt = decl.parent?.parent; const sf = ts.getSourceFileOfNode(decl); - if (stmt !== undefined && ts.isVariableStatement(stmt) && ts.isSourceFile(stmt.parent)) { + // A split require binding is bound at its assignment statement. + const splitCall = splitRequireCallOf7(program, decl); + const stmt = splitCall !== null ? splitRequireStatementOf7(splitCall) : decl.parent?.parent; + if ( + stmt !== undefined && + (ts.isVariableStatement(stmt) || splitCall !== null) && + ts.isSourceFile(stmt.parent) + ) { const stmts = sf.statements.nodes; - const k = stmts.indexOf(stmt); - const declarations = stmt.declarationList.declarations.nodes; + const k = stmts.indexOf(stmt as ts.Statement); + const declarations = ts.isVariableStatement(stmt) + ? stmt.declarationList.declarations.nodes + : []; // Earlier declarators run too: `const x = read(), dep = require('./dep')`. const precedingDecls = declarations.slice(0, declarations.indexOf(decl)); let firstRunnable = program.analysis.requireFirstRunnable.get(sf); @@ -1765,6 +1953,12 @@ export function requireBindingEarlyUse7( if (sym) bindings.add(sym); } if (bindings.size === 0) return null; + // A split require binding's assignment writes the binding; it reads nothing. + let splitWrite: ts.Node | null = splitRequireCallOf7(program, decl); + while (splitWrite !== null && ts.isParenthesizedExpression(splitWrite.parent)) + splitWrite = splitWrite.parent; + splitWrite = + splitWrite !== null && ts.isBinaryExpression(splitWrite.parent) ? splitWrite.parent.left : null; const stmts = sf.statements.nodes; const cjs = isCjsJsFile7(sf, program); const symbolOf = (id: ts.Identifier): ts.Symbol | undefined => { @@ -1988,7 +2182,7 @@ export function requireBindingEarlyUse7( const sym = symbolOf(n); if (sym === undefined) return undefined; if (bindings.has(sym)) { - if (exactEarlyRead?.(n) === true) return undefined; + if (n === splitWrite || exactEarlyRead?.(n) === true) return undefined; hit = n; return "stop"; } @@ -3499,7 +3693,7 @@ function cjsCycleRefusal7( } // Bindings of other members must stay unreachable from top-level code. for (const st of stmts) { - for (const req of requiresOf7(st)) { + for (const req of requiresOf7(st, program)) { if (req.decl === null) continue; const dep = resolveImport7(program, m, req.spec, "require"); if (dep === null || !members.has(dep)) continue; @@ -5775,7 +5969,7 @@ function preflight7(load: LoadResult): { // module aliases cannot represent; createRequire bindings have no // checked form either. const earlyRequireFence = ( - req: { decl: ts.VariableDeclaration | null }, + req: RequireOccurrence7, bindingKind: RequireCallBindingKind7, loc: { file: string; start: number; end: number }, ): boolean => { @@ -5783,6 +5977,7 @@ function preflight7(load: LoadResult): { if ( early === null || (bindingKind !== "createRequire" && + req.split === undefined && ((req.decl!.parent?.flags ?? 0) & (ts.NodeFlags.Const | ts.NodeFlags.Let)) !== 0) ) { return false; @@ -5793,14 +5988,16 @@ function preflight7(load: LoadResult): { loc, bindingKind === "createRequire" ? `createRequire() binding '${early.text}' below code that can reach it (Node throws ReferenceError on any earlier access, which is not modeled — move the require above the code that can run first)` - : `var require() binding '${early.text}' below code that can reach it (Node reads undefined before the require runs, which is not modeled — declare it with const or let, or move the require above the code that can run first)`, + : req.split !== undefined + ? `require() binding '${early.text}' assigned below code that can reach it (Node reads undefined before the assignment runs, which is not modeled — move the assignment above the code that can run first)` + : `var require() binding '${early.text}' below code that can reach it (Node reads undefined before the require runs, which is not modeled — declare it with const or let, or move the require above the code that can run first)`, ), ); return true; }; for (let k = 0; k < stmts.length; k++) { const stmt = stmts[k]!; - for (const req of requiresOf7(stmt)) { + for (const req of requiresOf7(stmt, program)) { const loc = { file: sf.fileName, start: ts.tokenStartOfNode(req.node), @@ -5827,8 +6024,8 @@ function preflight7(load: LoadResult): { const jsonDep = resolveImport7(program, sf, req.spec, "require"); if (jsonDep !== null && jsonDep.fileName.endsWith(".json")) { if (bindingKind === "createRequire") continue; - if (ts.isVariableStatement(stmt) && requiresOf7(stmt).length > 1) { - const others = requiresOf7(stmt).some((r) => { + if (ts.isVariableStatement(stmt) && requiresOf7(stmt, program).length > 1) { + const others = requiresOf7(stmt, program).some((r) => { const d = resolveImport7(program, sf, r.spec, "require"); return d === null || !d.fileName.endsWith(".json"); }); @@ -6000,8 +6197,12 @@ function preflight7(load: LoadResult): { // counts, and targets outside the compiled graph add nothing here: // their use sites keep their existing lowering fences. if (jsRequireFile && !isNodeEsmFile7(sf, program)) { + // A split require binding's assignment is a statement-level require + // edge (requiresOf7 above), parenthesized or not. + const splitCalls = new Set(splitRequireBindings7(program, sf).values()); for (const call of inlineRequiresOf7(sf)) { if (requireCallBindingKind7(program, call) !== "ambient") continue; + if (splitCalls.has(call)) continue; const spec = requireSpecOf7(call)!; if (load.externalTypes.has(spec) || canonicalBuiltinModule(spec) !== null) continue; const lazy = inDeferredPosition7(call); @@ -6750,6 +6951,7 @@ export { requireSpecOf7 as requireSpecOf, isRequireStatement7 as isRequireStatement, requiresOf7 as requiresOf, + splitRequireCallOf7 as splitRequireCallOf, isNodeEsmFile7 as isNodeEsmFile, resolveImport7 as resolveImport, resolveNpmImport7 as resolveNpmImport, diff --git a/packages/compiler/src/frontend/type-mapper.ts b/packages/compiler/src/frontend/type-mapper.ts index 8a9b59c9a..f51efd5f1 100644 --- a/packages/compiler/src/frontend/type-mapper.ts +++ b/packages/compiler/src/frontend/type-mapper.ts @@ -1433,16 +1433,18 @@ let mapTypeDepth = 0; let contextResolutions = 0; /** node:url's legacy record interfaces: url.parse()'s Url instance (and - * its two query-typed refinements), url.format()'s UrlObject input, and the - * URL form's URLFormatOptions. The values are checked-dynamic objects — - * Node's Url instance carries its class name and null fields, and format() - * reads any object's fields with JS truthiness. */ + * its two query-typed refinements), url.format()'s UrlObject input, the + * URL form's URLFormatOptions, and urlToHttpOptions's result. The values + * are checked-dynamic objects — Node's Url instance carries its class name + * and null fields, format() reads any object's fields with JS truthiness, + * and urlToHttpOptions answers a null-prototype object. */ const LEGACY_URL_TYPES = new Set([ "Url", "UrlObject", "UrlWithParsedQuery", "UrlWithStringQuery", "URLFormatOptions", + "UrlHttpOptions", ]); export function isLegacyUrlType( diff --git a/packages/compiler/src/index.ts b/packages/compiler/src/index.ts index 8b88ead00..81fffdeb4 100644 --- a/packages/compiler/src/index.ts +++ b/packages/compiler/src/index.ts @@ -1,4 +1,5 @@ import { optimizationField, type NativeOptimization } from "./backend/optimization.js"; +import { targetCpuField, targetCpuTargetRefusal } from "./backend/target-cpu.js"; import { compilationTiming, type CompilationTiming, type TimingClock } from "./timing.js"; import { prepareExecutableModule } from "./executable/prepare.js"; import { @@ -595,6 +596,7 @@ async function compileExecutableNative( ...(features.warningReplace ? { warningReplace: true } : {}), ...(features.stdioExtended ? { stdioExtended: true } : {}), zlib: features.zlib, + ...(features.brotli ? { brotli: true } : {}), assert: features.assert, inspect: features.inspect, dynInvoke: features.dynInvoke, @@ -808,6 +810,7 @@ async function prepareExecutableInput( lowRegion: lowRegionTarget(buildPlatform, opts.sanitize === true), ...(opts.sanitize === true ? { wasmBoundsChecks: true } : {}), ...inlineRcOption(opts.optimization, opts.sanitize === true), + ...targetCpuField(opts.targetCpu), }); } catch (err) { if (!(err instanceof LlvmUnsupportedError)) throw err; @@ -878,6 +881,7 @@ async function prepareExecutableInput( ...(opts.sanitize === true ? { wasmBoundsChecks: true } : {}), ...inlineRcOption(opts.optimization, opts.sanitize === true), ...(opts.detachedExit === true ? { detachedExit: true } : {}), + ...targetCpuField(opts.targetCpu), }); } catch (err) { if (!(err instanceof LlvmUnsupportedError)) throw err; @@ -1446,6 +1450,18 @@ async function compileTracked( } } } + const targetCpuRefusal = targetCpuTargetRefusal( + opts.targetCpu, + buildPlatform, + nativeCodegenTarget()?.architecture ?? process.arch, + ); + if (targetCpuRefusal !== null) { + return { + ok: false, + diagnostics: [nativeCodegenDiag("SC3002", targetCpuRefusal, entryPath)], + sourceTexts: new Map(), + }; + } try { windowsSubsystemLinkerArgs(buildPlatform, opts.windowsSubsystem); } catch (err) { @@ -1500,6 +1516,7 @@ async function compileTracked( ...(opts.strip ? { strip: true as const } : {}), ...(opts.windowsSubsystem === "gui" ? { windowsSubsystem: "gui" as const } : {}), ...(opts.detachedExit === true ? { detachedExit: true as const } : {}), + ...targetCpuField(opts.targetCpu), ...(profile === undefined ? {} : { profile: nativeProfileKey(profile) }), ...checkerField(), ...(youngNurseryRequested() ? { youngNursery: true as const } : {}), diff --git a/packages/compiler/src/ir/builtin-effects.ts b/packages/compiler/src/ir/builtin-effects.ts index 7682fe148..1e9bfd188 100644 --- a/packages/compiler/src/ir/builtin-effects.ts +++ b/packages/compiler/src/ir/builtin-effects.ts @@ -184,6 +184,13 @@ export const MAY_THROW_LIB_FNS: ReadonlySet = new Set([ "num.toStringRadix", "num.toStringRadixF64", "insp.jsonDyn", + // A checked-dynamic value the inspector does not render (a promise, a + // URL, a RegExp) throws the 'not supported yet' Error. + "insp.dyn", + "insp.dynS", + // %o's showHidden walk refuses the kinds whose hidden entries it cannot + // render. + "insp.dynHidden", // diagnostics_channel: publish runs subscribers synchronously (a throw // propagates — the documented divergence from triggerUncaughtException); // the subscribe/unsubscribe forms throw Node's ERR_INVALID_ARG_TYPE for @@ -744,6 +751,8 @@ export const MAY_THROW_LIB_FNS: ReadonlySet = new Set([ "url.set", "url.setChecked", "url.fileURLToPathUrl", + "fs.checkPath", + "fs.checkReadEncoding", "url.fileURLToPathChecked", "url.fileURLToPathOptions", "url.fileURLToPathBuffer", @@ -756,6 +765,8 @@ export const MAY_THROW_LIB_FNS: ReadonlySet = new Set([ "url.legacyResolve", "url.domainToASCII", "url.domainToUnicode", + // ERR_INVALID_ARG_TYPE and the credentials' URIError. + "url.toHttpOptions", // The win32-target flavor of pathToFileURL (same runtime entry point — // the bridge dispatches by the binary's platform): Node's win32 arm // raises ERR_INVALID_ARG_VALUE TypeErrors for malformed UNC inputs, so diff --git a/packages/compiler/src/ir/builtin-signatures.ts b/packages/compiler/src/ir/builtin-signatures.ts index 982550d72..3af5efcb4 100644 --- a/packages/compiler/src/ir/builtin-signatures.ts +++ b/packages/compiler/src/ir/builtin-signatures.ts @@ -1006,6 +1006,14 @@ export const LIB_FN_SIGS = defineLibFnSignatures({ "url.set": { argTypes: [URL_T, STRING, STRING], result: VOID }, "url.setChecked": { argTypes: [URL_T, STRING, DYN], result: VOID }, "url.fileURLToPathUrl": { argTypes: [URL_T], result: STRING }, + /** fileURLToPathUrl as a value: the path string, or the error it would + * throw (fs.existsSync and fs.promises URL paths). Never throws. */ + "url.fileURLToPathValue": { argTypes: [URL_T], result: DYN }, + /** getValidatedPath's null-byte check on a string path, and + * readFileSync's encoding check: what Node validates before it converts + * a later URL path. (path, argument name) and (encoding). */ + "fs.checkPath": { argTypes: [STRING, STRING], result: VOID }, + "fs.checkReadEncoding": { argTypes: [STRING], result: VOID }, "url.fileURLToPathChecked": { argTypes: [DYN], result: STRING }, "url.fileURLToPathOptions": { argTypes: [DYN, DYN], result: STRING }, /** node:url's legacy API (scr_url_legacy.c): parse(url, parseQueryString, @@ -1020,6 +1028,10 @@ export const LIB_FN_SIGS = defineLibFnSignatures({ "url.legacyResolve": { argTypes: [DYN, DYN, BOOL], result: STRING }, "url.domainToASCII": { argTypes: [DYN, BOOL], result: STRING }, "url.domainToUnicode": { argTypes: [DYN, BOOL], result: STRING }, + /** url.urlToHttpOptions over a checked-dynamic argument: a URL answers + * Node's null-prototype options object; a primitive or null throws + * ERR_INVALID_ARG_TYPE. */ + "url.toHttpOptions": { argTypes: [DYN], result: DYN }, /** node:punycode (scr_url.c): punycode.js 2.1.0's string conversions; * decode/toUnicode (and, past 32-bit deltas, encode/toASCII) throw the * module's RangeErrors, ucs2Encode String.fromCodePoint's. warn marks the @@ -3227,6 +3239,8 @@ export const LIB_FN_SIGS = defineLibFnSignatures({ * the +1 %Transform stream. flush takes the kind value, params the level * and strategy values; the Cb forms move their () => void callback. The * receivers are borrowed. */ + /** Connects scr_brotli.c to the zlib engine (%main, before any module). */ + "zlib.brotliInstall": { argTypes: [], result: VOID }, "zlib.streamNew": { argTypes: [F64, DYN], result: VOID }, "zlib.streamBytesWritten": { argTypes: [null], result: F64 }, /** `stream instanceof zlib.Gzip`: the borrowed stream and the class's @@ -4498,12 +4512,19 @@ export const LIB_FN_SIGS = defineLibFnSignatures({ "insp.buffer": { argTypes: [BYTES_U8], result: STRING }, /** A numeric typed array that is not a Buffer (any element kind). */ "insp.typedArray": { argTypes: [null, F64, F64], result: STRING }, + /** A u8 byte view in a union arm, element or field: a DataView, Buffer + * or Uint8Array by its own flags. */ + "insp.bytes": { argTypes: [null, F64, F64], result: STRING }, "insp.error": { argTypes: [null, F64, F64], result: STRING }, "insp.errorHasCause": { argTypes: [null], result: BOOL }, "insp.errorBagHasProperties": { argTypes: [DYN], result: BOOL }, "insp.errorCause": { argTypes: [null, F64, F64], result: STRING }, "insp.dyn": { argTypes: [DYN, F64, F64], result: STRING }, "insp.dynS": { argTypes: [DYN, F64], result: STRING }, + /** util.format's %o over a checked-dynamic value: inspect with + * showHidden. Kinds whose hidden entries have no rendering throw the + * 'not supported yet' Error. */ + "insp.dynHidden": { argTypes: [DYN, F64], result: STRING }, "insp.begin": { argTypes: [F64], result: VOID }, /** util.inspect's breakLength, compact (0 for false) and sorted for the * renders that follow; the call site restores 80, 3 and false afterwards. */ @@ -4539,6 +4560,11 @@ export const LIB_FN_SIGS = defineLibFnSignatures({ * `prefix inner` re-indented at the caller's level (+1). */ "insp.nestedBegin": { argTypes: [], result: VOID }, "insp.nestedEnd": { argTypes: [STRING, STRING], result: STRING }, + /** Around a top-level render that an inspection refusal can end: mark + * records the inspector's frame and nesting depth, unwind (in the + * render's finally) closes what the render left open above it. */ + "insp.mark": { argTypes: [], result: VOID }, + "insp.unwind": { argTypes: [], result: VOID }, /** node:string_decoder's utf8 StringDecoder (scr_string.c): the decoder * value is a one-field record whose f64 PACKS the pending partial * sequence (count + up to 3 raw bytes — Node buffers at most 3 for diff --git a/packages/compiler/src/ir/int32-slots.test.ts b/packages/compiler/src/ir/int32-slots.test.ts index be933ab38..0739bbb4f 100644 --- a/packages/compiler/src/ir/int32-slots.test.ts +++ b/packages/compiler/src/ir/int32-slots.test.ts @@ -281,6 +281,7 @@ test("dynamic stores disqualify the field names they can reach", () => { "dyn.typeof", "insp.dyn", "insp.dynS", + "insp.dynHidden", "dyn.objCreate", "dyn.getPrototype", "dyn.nameClassPrototype", @@ -357,6 +358,52 @@ test("an Error subclass constructor forwarding dynamic arguments stores no class expect(slots.isField("C", "a")).toBe(true); }); +test("Buffer.from over an ArrayBuffer range and Buffer as a value keep class fields int32", () => { + // `Buffer.from(view.buffer, offset, length)` passes its operands as + // checked values, and a program that reads the Buffer function's value + // installs it in %main; neither stores into a class instance. + const classes = [cls("C", ["a"])]; + const view: IrExpr = { loc, kind: "dynFrom", value: ref("o", obj("C")), type: DYN }; + const libCall = (fnName: string, args: IrExpr[], type: IrType = VOID): IrStmt => + stmt({ loc, kind: "libCall", fn: fnName, args, type } as IrExpr); + const slots = analyzeInt32Slots( + mod(classes, [ + fn( + "load", + [ + { id: "o", type: obj("C") }, + { id: "storage", type: DYN }, + ], + [ + set(ref("o", obj("C")), "C", "a", num(1)), + libCall("dyn.typedRefIs", [ + view, + { loc, kind: "strLit", value: "object:C", type: STRING }, + ]), + libCall("buffer.installValue", []), + libCall("buffer.constructor", [], DYN), + libCall( + "buffer.poolFromDynRange", + [ref("storage", DYN), num(2), num(4)].map((arg): IrExpr => + arg.type.kind === "dyn" ? arg : { loc, kind: "dynFrom", value: arg, type: DYN }, + ), + ), + libCall("buffer.poolFromDynOffset", [ + ref("storage", DYN), + { + loc, + kind: "dynFrom", + value: num(2), + type: DYN, + }, + ]), + ], + ), + ]), + ); + expect(slots.isField("C", "a")).toBe(true); +}); + test("captured bindings share one proof across the declaring function and its closures", () => { const closure: IrExpr = { loc, kind: "closure", fnName: "inner", captures: ["s"], type: DYN }; const outer = (): IrFunction => ({ diff --git a/packages/compiler/src/ir/int32-slots.ts b/packages/compiler/src/ir/int32-slots.ts index a359a18c5..06a173c1a 100644 --- a/packages/compiler/src/ir/int32-slots.ts +++ b/packages/compiler/src/ir/int32-slots.ts @@ -451,8 +451,14 @@ const DYN_READ_ONLY = new Set([ "fs.utimesSync", // Buffer.prototype members read as values: a lookup by key. "buffer.prototypeMember", + // Buffer.from(value, offset[, length]) over checked values: an + // ArrayBuffer's view after Node's offset and length conversions, or a copy + // of a string, array-like or typed array's values. + "buffer.poolFromDynOffset", + "buffer.poolFromDynRange", "insp.dyn", "insp.dynS", + "insp.dynHidden", // The dynamic-tier operators run their dyn twins (scr_js_value.c); the // conversions move a value between dyn and jsval, and js.toF64 is // dynCheck's number check. diff --git a/packages/compiler/src/ir/integer-loops.ts b/packages/compiler/src/ir/integer-loops.ts index d6942718a..2f7d2bea6 100644 --- a/packages/compiler/src/ir/integer-loops.ts +++ b/packages/compiler/src/ir/integer-loops.ts @@ -119,13 +119,26 @@ function stableLoopValue( stableLoopValue(value.receiver, locals, body, invariant, counter) ); case "bytesIntrinsic": - case "arrIntrinsic": + case "arrIntrinsic": { + // The receiver may be one arm of a union binding (indexed-unions.ts). + const receiver = + value.receiver.kind === "unionNarrow" ? value.receiver.value : value.receiver; return ( (value.method === "length" || (value.kind === "bytesIntrinsic" && value.method === "byteLength")) && - value.receiver.kind === "varRef" && - (value.kind === "bytesIntrinsic" || !invariant || stableLength(value.receiver.localId)) && - stableLoopValue(value.receiver, locals, body, invariant, counter) + receiver.kind === "varRef" && + (value.kind === "bytesIntrinsic" || !invariant || stableLength(receiver.localId)) && + stableLoopValue(receiver, locals, body, invariant, counter) + ); + } + // A union binding dispatched on its tag (indexed-unions.ts): stable + // when the binding is and every arm is. + case "ternary": + return ( + value.cond.kind === "unionIsTag" && + stableLoopValue(value.cond.value, locals, body, invariant, counter) && + stableLoopValue(value.then, locals, body, invariant, counter, stableLength) && + stableLoopValue(value.else_, locals, body, invariant, counter, stableLength) ); default: return false; diff --git a/packages/compiler/src/ir/ir.ts b/packages/compiler/src/ir/ir.ts index 550333edd..db93ec09c 100644 --- a/packages/compiler/src/ir/ir.ts +++ b/packages/compiler/src/ir/ir.ts @@ -1485,6 +1485,10 @@ export interface IrClassDef { jsName?: string; /** JavaScript constructor arity, ending before the first default or rest parameter. */ jsLength?: number; + /** The class declares public static fields. util.inspect prints them + * after the class tag; a class object reached through `unknown` does + * not carry them unless the runtime holds its static table. */ + ownStaticFields?: true; /** Zero-argument native helper returning the shared prototype data object. * Used when materializing an instance's own-property view. */ prototypeDataHelper?: string; @@ -1499,6 +1503,10 @@ export interface IrClassDef { * class of the chain sets `name` during construction, and then an own * `name` follows every other own property. */ errorNameAfter?: string | null; + /** JavaScript Error subclasses with a property bag: a view committed by a + * dynamic write keeps `name` and `message` where the bag recorded them + * (scr_error_dyn_follow_bag). */ + errorBagOrder?: boolean; /** Stable module symbol identities for public instance layout fields. */ symbolFields?: { field: string; globalId: string }[]; /** RUNTIME-PROVIDED class (the builtin Error hierarchy): the struct, RC @@ -1673,6 +1681,8 @@ export const ZLIB_STREAM_MODES: ReadonlyMap = new Map([ ["DeflateRaw", 5], ["InflateRaw", 6], ["Unzip", 7], + ["BrotliDecompress", 8], + ["BrotliCompress", 9], ]); export interface IrRecordShape { @@ -2507,6 +2517,14 @@ export type IrBytesIntrinsicMethod = | "indexOfNum" | "lastIndexOfNum" | "includesNum" + /** TypedArray.prototype.indexOf / lastIndexOf / includes on any element + * kind: [f64 needle, f64 fromIndex]. indexOf and lastIndexOf compare + * with strict equality (NaN is never found, -0 matches 0), includes with + * SameValueZero (NaN is found). An omitted fromIndex is 0, or +Infinity + * for lastIndexOf (which clamps to the last index). */ + | "indexOfElem" + | "lastIndexOfElem" + | "includesElem" | "fill" | "fillNum" | "fillStr" diff --git a/packages/compiler/src/ir/runtime-features.ts b/packages/compiler/src/ir/runtime-features.ts index cf1f30a4c..7da1c30ad 100644 --- a/packages/compiler/src/ir/runtime-features.ts +++ b/packages/compiler/src/ir/runtime-features.ts @@ -1152,6 +1152,9 @@ const RUNTIME_FEATURE_RULES = { ], }), zlib: rule({ prefixes: ["zlib."] }), + /** node:zlib's Brotli forms: zlib.brotliInstall, which %main calls when + * the program uses Brotli (scr_brotli.c). */ + brotli: rule({ fns: ["zlib.brotliInstall"] }), }; type RuntimeFeatureName = keyof typeof RUNTIME_FEATURE_RULES; @@ -1222,6 +1225,7 @@ function noRuntimeFeatures(): RuntimeFeatures { wasm: false, webcrypto: false, zlib: false, + brotli: false, }; } diff --git a/packages/compiler/src/ir/validate.ts b/packages/compiler/src/ir/validate.ts index d7eee18bf..a694e8d2c 100644 --- a/packages/compiler/src/ir/validate.ts +++ b/packages/compiler/src/ir/validate.ts @@ -2196,6 +2196,9 @@ function validateFunction( indexOfNum: { argTypes: [F64, F64], minArgs: 1, result: F64 }, lastIndexOfNum: { argTypes: [F64, F64], minArgs: 1, result: F64 }, includesNum: { argTypes: [F64, F64], minArgs: 1, result: BOOL }, + indexOfElem: { argTypes: [F64, F64], minArgs: 2, result: F64 }, + lastIndexOfElem: { argTypes: [F64, F64], minArgs: 2, result: F64 }, + includesElem: { argTypes: [F64, F64], minArgs: 2, result: BOOL }, fill: { argTypes: [BYTES_U8, F64, F64], minArgs: 1, result: BYTES_U8 }, fillNum: { argTypes: [F64, F64, F64], minArgs: 1, result: BYTES_U8 }, // Per-element TypedArray fill (any elem — the non-u8 fill path). diff --git a/packages/compiler/src/library/ir-policy.ts b/packages/compiler/src/library/ir-policy.ts index fde82f2b6..d4f57a44b 100644 --- a/packages/compiler/src/library/ir-policy.ts +++ b/packages/compiler/src/library/ir-policy.ts @@ -31,6 +31,7 @@ const LIB_MODE_REFUSED_PREFIXES: readonly [string, string][] = [ ["zlib.cbOpts", "the async node:zlib callback surface"], ["zlib.promise", "the async node:zlib callback surface (util.promisify)"], ["zlib.stream", "the node:zlib stream classes"], + ["zlib.brotliInstall", "node:zlib's Brotli forms"], ["process.stdoutWriteBytesCb", "process.stdout.write completion callbacks"], ["process.stderrWriteBytesCb", "process.stderr.write completion callbacks"], ["timers.", "the timers surface (setTimeout family)"], diff --git a/packages/compiler/src/native/executable-cache.test.ts b/packages/compiler/src/native/executable-cache.test.ts index 3199ef97f..91762f046 100644 --- a/packages/compiler/src/native/executable-cache.test.ts +++ b/packages/compiler/src/native/executable-cache.test.ts @@ -40,6 +40,11 @@ function fixture(debug = false) { const library = join(sdk, "libSystem.tbd"); writeFileSync(runtime, "runtime"); writeFileSync(library, "system library"); + // A directory's identity is its stat. Where the file system stamps times + // at the kernel tick, a file added within the tick of the last write + // leaves the directory's times unchanged; an old time makes every later + // change to the SDK directory visible. + utimesSync(sdk, 0, 0); const cache = new NativeCache(join(root, "cache")); const key = contentDigest("llvm and options"); const open = () => new NativeExecutableCache(cache, key, "clang", debug, [runtime]); diff --git a/packages/compiler/src/native/prepare.test.ts b/packages/compiler/src/native/prepare.test.ts index 112484f4a..7ae2d1d5f 100644 --- a/packages/compiler/src/native/prepare.test.ts +++ b/packages/compiler/src/native/prepare.test.ts @@ -2,7 +2,11 @@ import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSyn import { tmpdir } from "node:os"; import { join } from "node:path"; import { afterEach, expect, test } from "vitest"; -import { nativeCodegenTarget } from "../backend/targets.js"; +import { + LINUX_ARM64_GNU_TARGET, + nativeCodegenTarget, + WASM32_WASI_TARGET, +} from "../backend/targets.js"; import { runFrontend, type FrontendFactory } from "../frontend/pipeline.js"; import { loadProgram } from "../frontend/program-node.js"; import { ts7Executable } from "../frontend/ts7/rpc-api.js"; @@ -176,8 +180,31 @@ test("serialized IR travels as bounded parts through the frontend cache", () => const key = readdirSync(family).find((name) => /^[0-9a-f]{64}$/.test(name))!; const payload = JSON.parse(readFileSync(join(family, key), "utf8")); expect(payload.schema).toBe("scriptc.native-frontend.v3"); - expect(payload.input.llvm).toBe(""); + // The placeholders keep NativeExecutableInput's member types: the native + // compiler checks the parsed entry against them when it reads it back. + expect(payload.input.llvm).toEqual([]); expect(payload.input.ir).toBeNull(); expect(payload.llvm).toBe(first.llvm.join("")); expect(payload.ir).toEqual(first.ir); }); + +test("an x86-64 level is refused for targets that are not x86-64 before the frontend runs", () => { + const f = fixture(); + for (const target of [LINUX_ARM64_GNU_TARGET, WASM32_WASI_TARGET]) { + const result = prepareNativeExecutable( + f.entry, + { ...f.options, targetCpu: "x86-64-v3" }, + null, + { ...fixtureToolchain(), target }, + () => { + throw new Error("the frontend ran"); + }, + null, + ); + expect(result.ok).toBe(false); + if (result.ok) continue; + expect(result.diagnostics.map((d) => [d.code, d.message])).toEqual([ + ["SC3002", "--target-cpu=x86-64-v3 requires an x86-64 target"], + ]); + } +}); diff --git a/packages/compiler/src/native/prepare.ts b/packages/compiler/src/native/prepare.ts index 1530e8759..0ca2d712f 100644 --- a/packages/compiler/src/native/prepare.ts +++ b/packages/compiler/src/native/prepare.ts @@ -1,4 +1,5 @@ -import type { ScrDiagnostic } from "../diagnostics/diagnostic.js"; +import { targetCpuField, targetCpuTargetRefusal } from "../backend/target-cpu.js"; +import { nativeCodegenDiag, type ScrDiagnostic } from "../diagnostics/diagnostic.js"; import type { CompilationTiming } from "../timing.js"; import { readFileSync } from "node:fs"; import { basename, dirname, join, resolve } from "node:path"; @@ -59,7 +60,7 @@ export interface NativeExecutableInput { /** The two large artifacts follow the input metadata as separate members so * an entry can be written as parts instead of one JSON string; the stored - * input carries empty placeholders (`""`, `null`) for them. */ + * input carries empty placeholders (`[]`, `null`) for them. */ interface FrontendCacheEntry { schema: "scriptc.native-frontend.v3"; probes: FrontendInputSnapshot; @@ -78,7 +79,7 @@ function* frontendCacheParts( const metadata = JSON.stringify({ schema: "scriptc.native-frontend.v3", probes, - input: { ...input, llvm: "", ir: null }, + input: { ...input, llvm: [], ir: null }, }); yield metadata.slice(0, metadata.length - 1) + ',"llvm":"'; for (const part of joinedParts(input.llvm)) @@ -317,6 +318,17 @@ export function prepareNativeExecutable( timing: CompilationTiming = () => {}, ): NativeExecutableInput | CompileFailure { const outputKind = options.outputKind ?? "exe"; + const targetCpuRefusal = targetCpuTargetRefusal( + options.targetCpu, + toolchain.target.platform, + toolchain.target.architecture, + ); + if (targetCpuRefusal !== null) + return { + ok: false, + diagnostics: [nativeCodegenDiag("SC3002", targetCpuRefusal, entry)], + sourceTexts: new Map(), + }; const stem = basename(entry).replace(/\.(ts|mts|cts|js|mjs|cjs)$/, ""); const outputPaths = [ resolve(options.outPath), @@ -397,6 +409,7 @@ export function prepareNativeExecutable( forkPrimitives: emitForkPrimitives(), ...inlineRcOption(options.optimization, options.sanitize === true), ...(options.detachedExit === true && outputKind === "exe" ? { detachedExit: true } : {}), + ...targetCpuField(options.targetCpu), ...(options.optimization === "dev" && !options.strip ? { debugSources: prepared.sourceTexts } : {}), diff --git a/packages/compiler/src/native/sanitizer.test.ts b/packages/compiler/src/native/sanitizer.test.ts index e039d6404..969fa7785 100644 --- a/packages/compiler/src/native/sanitizer.test.ts +++ b/packages/compiler/src/native/sanitizer.test.ts @@ -86,6 +86,7 @@ test.skipIf(process.platform !== "linux" && process.platform !== "darwin")( builtinValues: false, warningReplace: false, stdioExtended: false, + brotli: false, regex: true, copying: false, textDecoderLegacy: false, diff --git a/packages/compiler/src/native/sanitizer.ts b/packages/compiler/src/native/sanitizer.ts index 6c1ff1e35..cb3728ec0 100644 --- a/packages/compiler/src/native/sanitizer.ts +++ b/packages/compiler/src/native/sanitizer.ts @@ -94,6 +94,7 @@ export function buildSanitizedRuntime( const quickjs = join(vendor, "quickjs-ng"); const zlib = join(vendor, "zlib"); const mbedtls = join(vendor, "mbedtls"); + const brotli = join(vendor, "brotli", "c"); const cacheIdentity = contentDigest( JSON.stringify({ schema: 1, @@ -137,6 +138,8 @@ export function buildSanitizedRuntime( zlib, "-I", join(mbedtls, "include"), + "-I", + join(brotli, "include"), ...(toolchain.target.platform === "linux" ? ["-ffunction-sections", "-fdata-sections"] : []), ]; const runtimeObjects: string[] = []; @@ -173,9 +176,23 @@ export function buildSanitizedRuntime( .filter((file) => file.endsWith(".c") && !file.startsWith(".")) .sort(); args = ["-std=c11", "-I", join(mbedtls, "include"), "-I", directory]; + } else if (name === "brotli") { + directory = brotli; + sources = ["common", "dec", "enc"] + .flatMap((dir) => + readdirSync(join(brotli, dir)) + .filter((file) => file.endsWith(".c") && !file.startsWith(".")) + .map((file) => `${dir}/${file}`), + ) + .sort(); + args = ["-std=c11", "-I", join(brotli, "include")]; } else throw new NativeCodegenError("SC3003", `unsupported runtime vendor archive: ${name}`); const objects = sources.map((source) => - compile(join(directory, source), name + "-" + source.replace(/\.c$/, ".o"), args), + compile( + join(directory, source), + name + "-" + source.replaceAll("/", "-").replace(/\.c$/, ".o"), + args, + ), ); const output = join(stage, "libscriptc-" + name + ".a"); runNativeTool( diff --git a/packages/compiler/surface-manifest.json b/packages/compiler/surface-manifest.json index 75541b8e5..1afd4cd3a 100644 --- a/packages/compiler/surface-manifest.json +++ b/packages/compiler/surface-manifest.json @@ -1,6 +1,6 @@ { "schemaVersion": 2, - "compilerVersion": "0.4.3", + "compilerVersion": "0.4.4", "coverage": [ "Entries are projected mechanically from the compiler's own decision tables: the diagnostics registry, the unsupported-syntax dispatch tables, the stdlib and node-builtin lowering tables, and the supported-builtin-module list. Nothing is hand-maintained; the manifest regenerates byte-identically from the source tree at this version.", "Absence from this manifest means 'not projected', never 'unsupported'. Surfaces lowered through dedicated code paths rather than tables are not yet projected: console, JSON, Promise/async and the timer surface, the net/http/tls/https/dgram/dns/assert/test/stream/readline module member surfaces, template literals, the regex slice, global functions (parseInt, parseFloat, isNaN, isFinite), and the process surface outside its ambient slice.", @@ -2469,6 +2469,12 @@ "name": "url.resolve", "status": "static" }, + { + "id": "node-builtin.url.urlToHttpOptions", + "kind": "node-builtin", + "name": "url.urlToHttpOptions", + "status": "static" + }, { "id": "node-builtin.util", "kind": "node-builtin", @@ -2876,22 +2882,6 @@ "status": "static", "note": "recognized module (bare and node:-prefixed specifiers)" }, - { - "id": "node-builtin.zlib.BrotliCompress", - "kind": "node-builtin", - "name": "zlib.BrotliCompress", - "status": "unsupported", - "code": "SC2020", - "note": "Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface" - }, - { - "id": "node-builtin.zlib.BrotliDecompress", - "kind": "node-builtin", - "name": "zlib.BrotliDecompress", - "status": "unsupported", - "code": "SC2020", - "note": "Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface" - }, { "id": "node-builtin.zlib.DEFLATE", "kind": "node-builtin", @@ -3645,33 +3635,25 @@ "id": "node-builtin.zlib.brotliCompress", "kind": "node-builtin", "name": "zlib.brotliCompress", - "status": "unsupported", - "code": "SC2020", - "note": "Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface" + "status": "static" }, { "id": "node-builtin.zlib.brotliCompressSync", "kind": "node-builtin", "name": "zlib.brotliCompressSync", - "status": "unsupported", - "code": "SC2020", - "note": "Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface" + "status": "static" }, { "id": "node-builtin.zlib.brotliDecompress", "kind": "node-builtin", "name": "zlib.brotliDecompress", - "status": "unsupported", - "code": "SC2020", - "note": "Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface" + "status": "static" }, { "id": "node-builtin.zlib.brotliDecompressSync", "kind": "node-builtin", "name": "zlib.brotliDecompressSync", - "status": "unsupported", - "code": "SC2020", - "note": "Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface" + "status": "static" }, { "id": "node-builtin.zlib.crc32", @@ -3683,17 +3665,13 @@ "id": "node-builtin.zlib.createBrotliCompress", "kind": "node-builtin", "name": "zlib.createBrotliCompress", - "status": "unsupported", - "code": "SC2020", - "note": "Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface" + "status": "static" }, { "id": "node-builtin.zlib.createBrotliDecompress", "kind": "node-builtin", "name": "zlib.createBrotliDecompress", - "status": "unsupported", - "code": "SC2020", - "note": "Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface" + "status": "static" }, { "id": "node-builtin.zlib.createDeflate", diff --git a/packages/compiler/test/class-method-mutations.test.ts b/packages/compiler/test/class-method-mutations.test.ts index 4871dda2b..166b9d556 100644 --- a/packages/compiler/test/class-method-mutations.test.ts +++ b/packages/compiler/test/class-method-mutations.test.ts @@ -167,3 +167,47 @@ test("a store into a dictionary whose values can be functions keeps checked disp ); expect(await callersOf(source, "%dyn.class.properties")).not.toEqual([]); }); + +test("a store into a generic dictionary of dictionaries keeps checked dispatch", async () => { + const source = dictionaries + .replace( + "interface Settings { groups: Record> }", + "interface Settings { groups: Record> }", + ) + .replace("function addGroup(settings: Settings,", "function addGroup(settings: Settings,") + .replace("const settings: Settings =", "const settings: Settings ="); + expect(await callersOf(source, "%dyn.class.properties")).not.toEqual([]); +}); + +test("a runtime-key store into a dictionary view of a class instance keeps checked dispatch", async () => { + const source = ` +class Counter { + n = 0; + tick(): number { return ++this.n; } +} +const counter = new Counter(); +const view: {} = counter; +const slots: Record = view; +const key: string = String(process.argv.length); +slots[key] = "replaced"; +console.log(counter.tick()); +`; + // The method has a slot the write can replace, which calls consult. + expect(await callersOf(source, "%Counter.tick")).toContain("%method.value:%Counter.tick"); +}); + +test("a dot store into a dictionary view of a class instance keeps checked dispatch", async () => { + const source = ` +class Lamp { + on = false; + toggle(): boolean { this.on = !this.on; return this.on; } +} +const lamp = new Lamp(); +const view: {} = lamp; +const slots: Record = view; +slots.toggle = "replaced"; +console.log(lamp.toggle()); +`; + // The method has a slot the write can replace, which calls consult. + expect(await callersOf(source, "%Lamp.toggle")).toContain("%method.value:%Lamp.toggle"); +}); diff --git a/packages/compiler/test/dictionary-views.test.ts b/packages/compiler/test/dictionary-views.test.ts new file mode 100644 index 000000000..a9cfd1056 --- /dev/null +++ b/packages/compiler/test/dictionary-views.test.ts @@ -0,0 +1,89 @@ +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { expect, test } from "vitest"; +import { compile, deserializeModule } from "../src/index.js"; + +/** The IR type kind of each named module-level binding. */ +async function globalKinds(source: string): Promise> { + const dir = await mkdtemp(join(tmpdir(), "scriptc-dictionary-views-")); + try { + const entry = join(dir, "main.ts"); + const outPath = join(dir, "main.ir.json"); + await writeFile(entry, source); + const result = await compile(entry, { outDir: dir, outPath, outputKind: "ir" }); + if (!result.ok) + throw new Error(result.diagnostics.map((d) => `${d.code}: ${d.message}`).join("\n")); + const mod = deserializeModule(await readFile(outPath, "utf8")); + return Object.fromEntries((mod.globals ?? []).map((g) => [g.name, g.type.kind])); + } finally { + await rm(dir, { recursive: true, force: true }); + } +} + +const program = (body: string): string => ` +const key = String(process.argv.length); +const counts: Record = { a: 1 }; +counts[key] = 2; +${body} +console.log(JSON.stringify(counts)); +`; + +test("a record written through a dictionary keeps that dictionary type checked", async () => { + const kinds = await globalKinds( + program(`const point: { a: string } = { a: "x" }; +const table: Record = point; +table[key] = "y"; +console.log(JSON.stringify(point));`), + ); + expect(kinds["table"]).toBe("dyn"); + // Dictionaries of other value types keep their native layout. + expect(kinds["counts"]).toBe("record"); +}); + +test("a record reaching a dictionary through a {} parameter keeps it checked", async () => { + const kinds = await globalKinds( + program(`function stamp(value: {}): void { + const inner: Record = value; + inner[key] = "y"; +} +const point: { a: string } = { a: "x" }; +stamp(point); +const other: Record = { b: "z" }; +console.log(JSON.stringify(point), other["b"]);`), + ); + expect(kinds["other"]).toBe("dyn"); +}); + +test("dictionaries keep their native layout without a record flowing in", async () => { + const kinds = await globalKinds( + program(`const table: Record = { a: "x" }; +table[key] = "y"; +const copy: Record = table; +copy[key] = "z"; +console.log(JSON.stringify(table));`), + ); + expect(kinds["table"]).toBe("record"); + expect(kinds["copy"]).toBe("record"); +}); + +test("a record converted to a dictionary that is only read keeps the native layout", async () => { + const kinds = await globalKinds( + program(`const point: { a: string } = { a: "x" }; +const table: Record = point; +console.log(table["a"]);`), + ); + expect(kinds["table"]).toBe("record"); +}); + +test("a dictionary literal whose methods read this keeps checked identity", async () => { + const kinds = await globalKinds( + program(`interface Table { [key: string]: () => number } +const methods: Table = { + base() { return 2; }, + twice() { return this.base() * 2; }, +}; +console.log(methods.twice());`), + ); + expect(kinds["methods"]).toBe("dyn"); +}); diff --git a/packages/compiler/test/integer-view-compares.test.ts b/packages/compiler/test/integer-view-compares.test.ts new file mode 100644 index 000000000..e988d48bd --- /dev/null +++ b/packages/compiler/test/integer-view-compares.test.ts @@ -0,0 +1,52 @@ +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { expect, test } from "vitest"; +import { compile, deserializeModule } from "../src/index.js"; +import { emitLlvmModule } from "../src/backend/llvm/emitter.js"; + +const source = `function siftDown(a: Int32Array, start: number, end: number): void { + let root = start; + while (2 * root + 1 < end) { + let child = 2 * root + 1; + if (child + 1 < end && a[child]! < a[child + 1]!) child++; + if (a[root]! >= a[child]!) return; + const t = a[root]!; + a[root] = a[child]!; + a[child] = t; + root = child; + } +} +const a = new Int32Array([3, 9, 1, 7, 5]); +siftDown(a, 0, Number(process.argv[2] ?? "5")); +console.log(Array.from(a).join()); +`; + +test("integer sums of speculated locals compare and index as integers", async () => { + const dir = await mkdtemp(join(tmpdir(), "scriptc-integer-views-")); + try { + const entry = join(dir, "sift.ts"); + await writeFile(entry, source); + const outPath = join(dir, "sift.ir.json"); + const result = await compile(entry, { outPath, outDir: dir, outputKind: "ir" }); + if (!result.ok) throw new Error(result.diagnostics.map((d) => d.message).join("\n")); + const ll = emitLlvmModule(deserializeModule(await readFile(outPath, "utf8"))); + const body = ll.match( + /define internal [^\n]+ @sc_bf_siftDown(?:\.i32)?\([^\n]*\) #0 \{([\s\S]*?)\n\}/, + )![1]!; + // `child + 1`: the integer the speculated copy already adds. + const sums = [...body.matchAll(/(%t\d+) = add nsw i64 %t\d+, 1\n/g)].map((m) => m[1]!); + expect(sums.length).toBeGreaterThan(0); + const uses = (op: string) => + sums.filter((sum) => new RegExp(`= ${op} i64 \\${sum}, %t\\d+\\n`).test(body)); + // `child + 1 < end` compares the integers, + expect(uses("icmp slt").length).toBeGreaterThan(0); + // and `a[child + 1]` bounds the integer index without a double round trip. + expect(uses("icmp ult").length).toBeGreaterThan(0); + // `2 * root + 1 < end` may pass 2^53, so it keeps the double compare. + expect(body).toMatch(/fmul double 0x4000000000000000, %t\d+\n\s+%t\d+ = mul nsw i64 2/); + expect(body).toContain("fcmp olt double"); + } finally { + await rm(dir, { recursive: true, force: true }); + } +}); diff --git a/packages/compiler/test/js-class-layouts.test.ts b/packages/compiler/test/js-class-layouts.test.ts index 110d007ee..987703110 100644 --- a/packages/compiler/test/js-class-layouts.test.ts +++ b/packages/compiler/test/js-class-layouts.test.ts @@ -221,3 +221,21 @@ test("a JavaScript file TypeScript checks uses its JSDoc types for class layouts expect(layout(unchecked, "Account").fields).toBe("owner:dyn balance:dyn"); expect(params(unchecked, "%Account.constructor")).toBe("(object, dyn, dyn): void"); }); + +test("instances of a class with subclasses box at their exact class", async () => { + const module = await lower(`${SHAPES} +/** @param {any} value */ +function keep(value) { + return value; +} +/** @param {Shape} shape */ +function cross(shape) { + return keep(shape); +} +console.log(cross(new Square()).size, cross(new Shape()).label); +`); + const helper = module.functions.find((fn) => fn.name === "%dyn.class.boxExact:Shape"); + expect(helper).toBeDefined(); + expect(calls(module, "cross")).toContain("%dyn.class.boxExact:Shape"); + expect(JSON.stringify(helper!.body)).toContain('"className":"Square"'); +}); diff --git a/packages/compiler/test/native-codegen-lowering.test.ts b/packages/compiler/test/native-codegen-lowering.test.ts index e9891e945..857393f21 100644 --- a/packages/compiler/test/native-codegen-lowering.test.ts +++ b/packages/compiler/test/native-codegen-lowering.test.ts @@ -51,14 +51,12 @@ test("decompression options lower for run-time validation", () => { expect(diags).toEqual([]); }); -test("Brotli keeps its SC2020 refusal", () => { +test("Brotli options lower for run-time validation", () => { const diags = diagnostics(` - import { brotliCompressSync } from "node:zlib"; - console.log(brotliCompressSync("payload").length); + import { brotliCompressSync, constants } from "node:zlib"; + console.log(brotliCompressSync("payload", { params: { [constants.BROTLI_PARAM_QUALITY]: 4 } }).length); `); - expect(diags).toHaveLength(1); - expect(diags[0]!.code).toBe("SC2020"); - expect(diags[0]!.message).toContain("brotliCompressSync"); + expect(diags).toEqual([]); }); test("union writes keep the refusal for incompatible field storage", () => { diff --git a/packages/compiler/test/power-of-two-quotient-emission.test.ts b/packages/compiler/test/power-of-two-quotient-emission.test.ts new file mode 100644 index 000000000..4b748a2a1 --- /dev/null +++ b/packages/compiler/test/power-of-two-quotient-emission.test.ts @@ -0,0 +1,46 @@ +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { expect, test } from "vitest"; +import { compile, deserializeModule } from "../src/index.js"; +import { emitLlvmModule } from "../src/backend/llvm/emitter.js"; + +test("a quotient by Math.pow(2, n) multiplies by the divisor's reciprocal power of two", async () => { + const dir = await mkdtemp(join(tmpdir(), "scriptc-pow2-quotient-")); + try { + const entry = join(dir, "main.ts"); + const outPath = join(dir, "main.ir.json"); + await writeFile( + entry, + ` +function scaled(x: number, n: number): number { return x / Math.pow(2, n); } +function plain(x: number, d: number): number { return x / d; } +function other(x: number, n: number): number { return x / Math.pow(3, n); } +console.log(scaled(3, 4), plain(3, 16), other(3, 4)); +`, + ); + const result = await compile(entry, { outDir: dir, outPath, outputKind: "ir" }); + if (!result.ok) + throw new Error(result.diagnostics.map((d) => `${d.code}: ${d.message}`).join("\n")); + const mod = deserializeModule(await readFile(outPath, "utf8")); + const ll = emitLlvmModule(mod); + const fn = (name: string): string => + new RegExp(`^define internal [^\\n]*@sc_[bf]+_${name}(?:\\.i32)?\\([^]*?^}`, "m").exec( + ll, + )![0]; + // The reciprocal's bits are 0x7FE0000000000000 minus the divisor's; a + // divisor that is not a power of two from 2^-1022 to 2^1022 divides. + const quotient = fn("scaled"); + expect(quotient).toContain(`sub i64 ${0x7fe0000000000000n}, `); + expect(quotient).toMatch(/fmul double %\w+, %\w+/); + expect(quotient).toMatch(/icmp ult i64 %\w+, 2045/); + expect(quotient).toMatch(/select i1 %\w+, double %\w+, double %\w+/); + expect(quotient.match(/ = fdiv double /g)).toHaveLength(1); + for (const name of ["plain", "other"]) { + expect(fn(name)).not.toContain(`${0x7fe0000000000000n}`); + expect(fn(name)).toMatch(/fdiv double/); + } + } finally { + await rm(dir, { recursive: true, force: true }); + } +}); diff --git a/packages/compiler/test/target-cpu-emit.test.ts b/packages/compiler/test/target-cpu-emit.test.ts new file mode 100644 index 000000000..5dee8243c --- /dev/null +++ b/packages/compiler/test/target-cpu-emit.test.ts @@ -0,0 +1,46 @@ +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { expect, test } from "vitest"; +import { compile } from "../src/index.js"; + +const program = `const a = new Int32Array(4096); +for (let i = 0; i < a.length; i++) a[i] = (i * 2654435761) | 0; +let s = 0; +for (let r = 0; r < 64; r++) for (let i = 0; i < a.length; i++) s = (s + a[i]!) | 0; +console.log(s); +`; + +test.runIf(process.platform === "linux" && process.arch === "x64")( + "assembly, object and LLVM builds honor the target CPU", + async () => { + const dir = await mkdtemp(join(tmpdir(), "scriptc-target-cpu-emit-")); + const entry = join(dir, "main.ts"); + const emit = async ( + outputKind: "llvm" | "asm" | "obj", + targetCpu?: "x86-64-v3", + ): Promise => { + const outPath = join(dir, `main-${outputKind}-${targetCpu ?? "baseline"}`); + const result = await compile(entry, { + outPath, + outDir: dir, + outputKind, + ...(targetCpu === undefined ? {} : { targetCpu }), + }); + if (!result.ok) throw new Error(result.diagnostics.map((d) => d.message).join("\n")); + return readFile(outPath); + }; + try { + await writeFile(entry, program); + expect((await emit("llvm")).toString()).not.toContain('"target-cpu"'); + expect((await emit("llvm", "x86-64-v3")).toString()).toContain('"target-cpu"="x86-64-v3"'); + // The v3 build vectorizes the sums with AVX2's 256-bit registers. + expect((await emit("asm")).toString()).not.toContain("%ymm"); + expect((await emit("asm", "x86-64-v3")).toString()).toContain("%ymm"); + expect((await emit("obj", "x86-64-v3")).equals(await emit("obj"))).toBe(false); + } finally { + await rm(dir, { recursive: true, force: true }); + } + }, + 240_000, +); diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6343-inspect-class-values.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6343-inspect-class-values.ts.json new file mode 100644 index 000000000..4fa8625ac --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6343-inspect-class-values.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/6343-inspect-class-values.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6344-inspect-function-properties.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6344-inspect-function-properties.cjs.json new file mode 100644 index 000000000..003075140 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6344-inspect-function-properties.cjs.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/6344-inspect-function-properties.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6357-format-o-hidden.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6357-format-o-hidden.ts.json new file mode 100644 index 000000000..cf0cd31d1 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6357-format-o-hidden.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/6357-format-o-hidden.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6358-format-o-hidden-js.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6358-format-o-hidden-js.cjs.json new file mode 100644 index 000000000..73d4eefa6 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6358-format-o-hidden-js.cjs.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/6358-format-o-hidden-js.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6935-fs-url-paths-ordered.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6935-fs-url-paths-ordered.ts.json new file mode 100644 index 000000000..ec3d3f004 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/6935-fs-url-paths-ordered.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/6935-fs-url-paths-ordered.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7012-dictionary-views-keep-objects.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7012-dictionary-views-keep-objects.ts.json new file mode 100644 index 000000000..6d7944cf7 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7012-dictionary-views-keep-objects.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7012-dictionary-views-keep-objects.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7013-dictionary-view-parameter.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7013-dictionary-view-parameter.ts.json new file mode 100644 index 000000000..41f80c41e --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7013-dictionary-view-parameter.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7013-dictionary-view-parameter.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7189-non-null-assertion-nullish-destination.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7189-non-null-assertion-nullish-destination.ts.json new file mode 100644 index 000000000..dc0d277ee --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7189-non-null-assertion-nullish-destination.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7189-non-null-assertion-nullish-destination.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7392-non-null-operands.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7392-non-null-operands.ts.json new file mode 100644 index 000000000..be7ffaa53 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7392-non-null-operands.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7392-non-null-operands.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7394-non-null-typed-array-reads.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7394-non-null-typed-array-reads.ts.json new file mode 100644 index 000000000..5fbae0c10 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7394-non-null-typed-array-reads.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7394-non-null-typed-array-reads.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7453-untyped-overload-results.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7453-untyped-overload-results.cjs.json new file mode 100644 index 000000000..9ba935c1e --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7453-untyped-overload-results.cjs.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7453-untyped-overload-results.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7624-key-order-boxed-callback-records/main.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7624-key-order-boxed-callback-records/main.ts.json new file mode 100644 index 000000000..1a617ef56 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7624-key-order-boxed-callback-records/main.ts.json @@ -0,0 +1,7 @@ +{ + "order": [ + "/tests/corpus/7624-key-order-boxed-callback-records/lib.js", + "/tests/corpus/7624-key-order-boxed-callback-records/main.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7680-typed-array-search.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7680-typed-array-search.ts.json new file mode 100644 index 000000000..d93d9afdc --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7680-typed-array-search.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7680-typed-array-search.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7681-typed-array-search-dynamic.mjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7681-typed-array-search-dynamic.mjs.json new file mode 100644 index 000000000..ab91940c0 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7681-typed-array-search-dynamic.mjs.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7681-typed-array-search-dynamic.mjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7682-constructor-function-globals.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7682-constructor-function-globals.js.json new file mode 100644 index 000000000..26d05338c --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7682-constructor-function-globals.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7682-constructor-function-globals.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7714-zlib-brotli-compress.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7714-zlib-brotli-compress.cjs.json new file mode 100644 index 000000000..fb8e2d1d9 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7714-zlib-brotli-compress.cjs.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7714-zlib-brotli-compress.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7715-zlib-brotli-decompress.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7715-zlib-brotli-decompress.cjs.json new file mode 100644 index 000000000..4a40657b1 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7715-zlib-brotli-decompress.cjs.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7715-zlib-brotli-decompress.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7716-zlib-brotli.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7716-zlib-brotli.ts.json new file mode 100644 index 000000000..b410a8230 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7716-zlib-brotli.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7716-zlib-brotli.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7745-typed-array-unions.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7745-typed-array-unions.ts.json new file mode 100644 index 000000000..9c770f8dd --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7745-typed-array-unions.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7745-typed-array-unions.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7747-typed-array-class-values.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7747-typed-array-class-values.ts.json new file mode 100644 index 000000000..a18e9e7df --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7747-typed-array-class-values.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7747-typed-array-class-values.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7748-typed-array-number-array-unions.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7748-typed-array-number-array-unions.ts.json new file mode 100644 index 000000000..783fb1435 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7748-typed-array-number-array-unions.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7748-typed-array-number-array-unions.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7749-typed-array-element-searches.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7749-typed-array-element-searches.ts.json new file mode 100644 index 000000000..8a1372cea --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7749-typed-array-element-searches.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7749-typed-array-element-searches.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7750-typed-array-union-inspect.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7750-typed-array-union-inspect.ts.json new file mode 100644 index 000000000..26cc31982 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7750-typed-array-union-inspect.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7750-typed-array-union-inspect.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7752-typed-array-dynamic-methods.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7752-typed-array-dynamic-methods.js.json new file mode 100644 index 000000000..78c9633d6 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7752-typed-array-dynamic-methods.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7752-typed-array-dynamic-methods.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7796-boxed-subclass-identity.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7796-boxed-subclass-identity.js.json new file mode 100644 index 000000000..37f785cc2 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7796-boxed-subclass-identity.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7796-boxed-subclass-identity.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7982-integer-view-compares.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7982-integer-view-compares.ts.json new file mode 100644 index 000000000..94919aab0 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7982-integer-view-compares.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7982-integer-view-compares.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7991-unknown-class-union-casts.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7991-unknown-class-union-casts.ts.json new file mode 100644 index 000000000..68185e837 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/7991-unknown-class-union-casts.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/7991-unknown-class-union-casts.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8101-url-host-and-path-parsing.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8101-url-host-and-path-parsing.js.json new file mode 100644 index 000000000..d38f437bc --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8101-url-host-and-path-parsing.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8101-url-host-and-path-parsing.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8102-url-path-to-file-url-unc-hosts.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8102-url-path-to-file-url-unc-hosts.js.json new file mode 100644 index 000000000..987c72578 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8102-url-path-to-file-url-unc-hosts.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8102-url-path-to-file-url-unc-hosts.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8103-url-inspect.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8103-url-inspect.ts.json new file mode 100644 index 000000000..06632e9e7 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8103-url-inspect.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8103-url-inspect.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8104-url-to-http-options.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8104-url-to-http-options.ts.json new file mode 100644 index 000000000..aedf0a20c --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8104-url-to-http-options.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8104-url-to-http-options.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8110-builtin-prototype-own-members.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8110-builtin-prototype-own-members.js.json new file mode 100644 index 000000000..033847082 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8110-builtin-prototype-own-members.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8110-builtin-prototype-own-members.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8111-plain-object-check-unknown.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8111-plain-object-check-unknown.ts.json new file mode 100644 index 000000000..2986186a2 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8111-plain-object-check-unknown.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8111-plain-object-check-unknown.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8112-error-factory-own-key-order.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8112-error-factory-own-key-order.js.json new file mode 100644 index 000000000..4b64d1d75 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8112-error-factory-own-key-order.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8112-error-factory-own-key-order.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8113-error-class-field-before-name.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8113-error-class-field-before-name.js.json new file mode 100644 index 000000000..ddf5981f0 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8113-error-class-field-before-name.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8113-error-class-field-before-name.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8115-error-prototype-identity.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8115-error-prototype-identity.js.json new file mode 100644 index 000000000..f4a6f13f0 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8115-error-prototype-identity.js.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8115-error-prototype-identity.js" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8129-brotli-long-param-name.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8129-brotli-long-param-name.cjs.json new file mode 100644 index 000000000..33ef96201 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8129-brotli-long-param-name.cjs.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8129-brotli-long-param-name.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8160-assert-expected-from-fields.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8160-assert-expected-from-fields.cjs.json new file mode 100644 index 000000000..fcaacbbee --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8160-assert-expected-from-fields.cjs.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8160-assert-expected-from-fields.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8180-pow2-quotients.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8180-pow2-quotients.ts.json new file mode 100644 index 000000000..58c36cf5d --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/8180-pow2-quotients.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/8180-pow2-quotients.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/split-cjs-require-binding/main.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/split-cjs-require-binding/main.cjs.json new file mode 100644 index 000000000..60b9b0736 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/split-cjs-require-binding/main.cjs.json @@ -0,0 +1,12 @@ +{ + "order": [ + "/tests/corpus/split-cjs-require-binding/lib.cjs", + "/tests/corpus/split-cjs-require-binding/whole.cjs", + "/tests/corpus/split-cjs-require-binding/reexport.cjs", + "/tests/corpus/split-cjs-require-binding/reexport-extra.cjs", + "/tests/corpus/split-cjs-require-binding/chain.cjs", + "/tests/corpus/split-cjs-require-binding/chain-wrap.cjs", + "/tests/corpus/split-cjs-require-binding/main.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/split-cjs-require-cycle/main.cjs.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/split-cjs-require-cycle/main.cjs.json new file mode 100644 index 000000000..0ea3366d3 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/split-cjs-require-cycle/main.cjs.json @@ -0,0 +1,8 @@ +{ + "order": [ + "/tests/corpus/split-cjs-require-cycle/odd.cjs", + "/tests/corpus/split-cjs-require-cycle/even.cjs", + "/tests/corpus/split-cjs-require-cycle/main.cjs" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/typed-array-masked-index-stores.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/typed-array-masked-index-stores.ts.json new file mode 100644 index 000000000..dde5a96fa --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/corpus/typed-array-masked-index-stores.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/corpus/typed-array-masked-index-stores.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/diagnostics/split-cjs-require-cycle/main.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/diagnostics/split-cjs-require-cycle/main.js.json new file mode 100644 index 000000000..90d4a2353 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/diagnostics/split-cjs-require-cycle/main.js.json @@ -0,0 +1,19 @@ +{ + "order": [ + "/tests/diagnostics/split-cjs-require-cycle/b.js", + "/tests/diagnostics/split-cjs-require-cycle/main.js" + ], + "diags": [ + { + "code": "SC1016", + "message": "circular imports (/tests/diagnostics/split-cjs-require-cycle/main.js → /tests/diagnostics/split-cjs-require-cycle/b.js → /tests/diagnostics/split-cjs-require-cycle/main.js; the cycle closes through a require() edge: /tests/diagnostics/split-cjs-require-cycle/main.js uses its exports at /tests/diagnostics/split-cjs-require-cycle/main.js:10 outside the export statements that precede its first require, so a module of the cycle can observe them before they settle) are not supported yet", + "loc": { + "file": "/tests/diagnostics/split-cjs-require-cycle/main.js", + "start": 0, + "end": 0 + }, + "milestone": "later", + "hint": "ES-module cycles of let/const/function bindings compile as-is; rewrite the named construct (a named import instead of a namespace, a const instead of a default-export expression or var, a class declared before the code that can reach it) or break the named edge" + } + ] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/diagnostics/split-cjs-require-early/main.js.json b/packages/compiler/test/ts7/baselines/order-parity/tests/diagnostics/split-cjs-require-early/main.js.json new file mode 100644 index 000000000..acb338494 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/diagnostics/split-cjs-require-early/main.js.json @@ -0,0 +1,27 @@ +{ + "order": [ + "/tests/diagnostics/split-cjs-require-early/main.js" + ], + "diags": [ + { + "code": "SC1013", + "message": "require() binding 'lib' assigned below code that can reach it (Node reads undefined before the assignment runs, which is not modeled — move the assignment above the code that can run first) is not supported yet", + "loc": { + "file": "/tests/diagnostics/split-cjs-require-early/main.js", + "start": 396, + "end": 415 + }, + "milestone": "later" + }, + { + "code": "SC1013", + "message": "require() binding 'wrapped' assigned below code that can reach it (Node reads undefined before the assignment runs, which is not modeled — move the assignment above the code that can run first) is not supported yet", + "loc": { + "file": "/tests/diagnostics/split-cjs-require-early/main.js", + "start": 530, + "end": 549 + }, + "milestone": "later" + } + ] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/node-types/fs-url-fallible.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/node-types/fs-url-fallible.ts.json new file mode 100644 index 000000000..e4967ea93 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/node-types/fs-url-fallible.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/fixtures/node-types/fs-url-fallible.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/node-types/fs-url-path-fences.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/node-types/fs-url-path-fences.ts.json deleted file mode 100644 index 7b63a5564..000000000 --- a/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/node-types/fs-url-path-fences.ts.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "order": [ - "/tests/fixtures/node-types/fs-url-path-fences.ts" - ], - "diags": [] -} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/npm/cases/hono-zod-default-hook/main.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/npm/cases/hono-zod-default-hook/main.ts.json new file mode 100644 index 000000000..2310d6e0f --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/npm/cases/hono-zod-default-hook/main.ts.json @@ -0,0 +1,61 @@ +{ + "order": [ + "/tests/fixtures/npm/cases/hono-zod-default-hook/main.ts" + ], + "diags": [ + { + "code": "SC0001", + "message": "Cannot find name 'WebSocket'.", + "loc": { + "file": "/tests/fixtures/npm/node_modules/hono/dist/types/client/types.d.ts", + "start": 1398, + "end": 1407 + } + }, + { + "code": "SC0001", + "message": "Cannot find name 'WebSocket'.", + "loc": { + "file": "/tests/fixtures/npm/node_modules/hono/dist/types/client/types.d.ts", + "start": 1413, + "end": 1422 + } + }, + { + "code": "SC0001", + "message": "Cannot find name 'WebSocket'.", + "loc": { + "file": "/tests/fixtures/npm/node_modules/hono/dist/types/client/types.d.ts", + "start": 3716, + "end": 3725 + } + }, + { + "code": "SC0001", + "message": "Cannot find name 'FormData'.", + "loc": { + "file": "/tests/fixtures/npm/node_modules/hono/dist/types/client/types.d.ts", + "start": 4798, + "end": 4806 + } + }, + { + "code": "SC0001", + "message": "Cannot find name 'FormData'.", + "loc": { + "file": "/tests/fixtures/npm/node_modules/hono/dist/types/request.d.ts", + "start": 549, + "end": 557 + } + }, + { + "code": "SC0001", + "message": "Cannot find name 'FormData'.", + "loc": { + "file": "/tests/fixtures/npm/node_modules/hono/dist/types/request.d.ts", + "start": 5572, + "end": 5580 + } + } + ] +} diff --git a/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/npm/cases/zod4-record/main.ts.json b/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/npm/cases/zod4-record/main.ts.json new file mode 100644 index 000000000..8c7700ac8 --- /dev/null +++ b/packages/compiler/test/ts7/baselines/order-parity/tests/fixtures/npm/cases/zod4-record/main.ts.json @@ -0,0 +1,6 @@ +{ + "order": [ + "/tests/fixtures/npm/cases/zod4-record/main.ts" + ], + "diags": [] +} diff --git a/packages/compiler/test/typed-array-union-emission.test.ts b/packages/compiler/test/typed-array-union-emission.test.ts new file mode 100644 index 000000000..e9bb22103 --- /dev/null +++ b/packages/compiler/test/typed-array-union-emission.test.ts @@ -0,0 +1,116 @@ +import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { expect, test } from "vitest"; +import { compile } from "../src/index.js"; + +async function emitLlvm(source: string): Promise { + const dir = await mkdtemp(join(tmpdir(), "scriptc-typed-array-unions-")); + try { + const entry = join(dir, "main.ts"); + const outPath = join(dir, "main.ll"); + await writeFile(entry, source); + const result = await compile(entry, { outDir: dir, outPath, outputKind: "llvm" }); + expect(result.ok, JSON.stringify(result.diagnostics)).toBe(true); + return await readFile(outPath, "utf8"); + } finally { + await rm(dir, { recursive: true, force: true }); + } +} + +function body(llvm: string, name: string): string { + return new RegExp(`^define [^@]*@sc_b?f_${name}(\\.i32)?\\([^]*?^}`, "m").exec(llvm)?.[0] ?? ""; +} + +const source = ` +type UintArray = Uint8Array | Uint16Array | Uint32Array; +const pick = (max: number, n: number): UintArray => + max <= 256 ? new Uint8Array(n) : max <= 65536 ? new Uint16Array(n) : new Uint32Array(n); +function total(xs: UintArray): number { + let s = 0; + for (let i = 0; i < xs.length; i++) s += xs[i]!; + return s; +} +function first(max: number): number { + return pick(max, 4)[0]!; +} +const xs = pick(Number(process.argv.length) * 100000, 8); +for (let i = 0; i < xs.length; i++) xs[i] = i; +console.log(total(xs), first(10)); +`; + +test("element reads of a union of typed arrays load each arm's own element kind in place", async () => { + const llvm = await emitLlvm(source); + const total = body(llvm, "total"); + // One load per arm, each of its element width, behind the union's tag. + for (const width of ["i8", "i16", "i32"]) expect(total).toMatch(new RegExp(`load ${width}, ptr`)); + expect(total).not.toContain("@sc_bf__x25_union_getNumber"); + // The loop over the union's length keeps an integer counter. + expect(total).toMatch(/alloca i64/); +}); + +test("a typed-array union read through a computed receiver goes through one helper", async () => { + const llvm = await emitLlvm(source); + // The receiver is a call: evaluated once, then dispatched by the helper. + expect(body(llvm, "first")).toContain("@sc_bf__x25_union_getNumber"); +}); + +const stores = ` +type Wide = Uint8Array | Uint16Array; +const pick = (wide: boolean): Wide => (wide ? new Uint16Array(4) : new Uint8Array(4)); +function fill(xs: Wide): void { + for (let i = 0; i < xs.length; i++) xs[i] = i + 1; +} +function rebind(): void { + let u = pick(false); + let i = 0; + const swap = (): number => { + u = pick(true); + i = 2; + return 3; + }; + u[i] = swap(); + console.log(u, i); +} +fill(pick(process.argv.length > 9)); +rebind(); +`; + +test("a typed-array union store runs in place unless its value can rebind the receiver or index", async () => { + const llvm = await emitLlvm(stores); + expect(body(llvm, "fill")).not.toContain("@sc_bf__x25_union_idxSet"); + // The call may assign the captured receiver and index, which the store + // read before it: the helper evaluates them first. + expect(body(llvm, "rebind")).toContain("@sc_bf__x25_union_idxSet"); +}); + +test("typed-array methods on a union with a Buffer arm need a narrowing first", async () => { + const dir = await mkdtemp(join(tmpdir(), "scriptc-typed-array-unions-")); + try { + const entry = join(dir, "main.ts"); + // The Buffer arm is found by its type, also through an alias name. + for (const [declaration, method] of [ + ["const u: Buffer | Uint16Array", "slice(1)"], + ["type Bytes = Uint16Array | Buffer;\nconst u: Bytes", "slice(1)"], + ["type Bytes = Uint16Array | Buffer;\nconst u: Bytes", "fill(1)"], + ["type Bytes = Uint16Array | Buffer;\nconst u: Bytes", "indexOf(1)"], + ]) { + await writeFile( + entry, + `import { Buffer } from "node:buffer"; +${declaration} = process.argv.length > 9 ? new Uint16Array(2) : Buffer.alloc(2); +console.log(u.${method}); +`, + ); + const result = await compile(entry, { + outDir: dir, + outPath: join(dir, "main.ll"), + outputKind: "llvm", + }); + expect(result.ok, `${declaration} ${method}`).toBe(false); + expect(JSON.stringify(result.diagnostics)).toContain(method.slice(0, method.indexOf("("))); + } + } finally { + await rm(dir, { recursive: true, force: true }); + } +}); diff --git a/packages/experimental/package.json b/packages/experimental/package.json index b3e8a6fb1..583a2bc58 100644 --- a/packages/experimental/package.json +++ b/packages/experimental/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/experimental", - "version": "0.4.3", + "version": "0.4.4", "description": "Experimental scriptc APIs, with Node.js implementations: lifetime regions for ProgramLifetime objects, intern tables shared between threads, and per-thread slots on shared objects", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/llvm-darwin-arm64/package.json b/packages/llvm-darwin-arm64/package.json index ac99f1661..76d5fdb72 100644 --- a/packages/llvm-darwin-arm64/package.json +++ b/packages/llvm-darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/llvm-darwin-arm64", - "version": "0.4.3", + "version": "0.4.4", "description": "Pinned LLVM code-generation helper for scriptc on macOS arm64", "license": "Apache-2.0 WITH LLVM-exception", "homepage": "https://scriptc.dev", diff --git a/packages/llvm-darwin-x64/package.json b/packages/llvm-darwin-x64/package.json index ca632dcd4..fbb755f4a 100644 --- a/packages/llvm-darwin-x64/package.json +++ b/packages/llvm-darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/llvm-darwin-x64", - "version": "0.4.3", + "version": "0.4.4", "description": "Pinned LLVM code-generation helper for scriptc on macOS x64", "license": "Apache-2.0 WITH LLVM-exception", "homepage": "https://scriptc.dev", diff --git a/packages/llvm-linux-arm64-gnu/package.json b/packages/llvm-linux-arm64-gnu/package.json index 566b38e40..81fdc7d5b 100644 --- a/packages/llvm-linux-arm64-gnu/package.json +++ b/packages/llvm-linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/llvm-linux-arm64-gnu", - "version": "0.4.3", + "version": "0.4.4", "description": "Pinned LLVM code-generation helper for scriptc on Linux arm64", "license": "Apache-2.0 WITH LLVM-exception", "homepage": "https://scriptc.dev", diff --git a/packages/llvm-linux-arm64-musl/package.json b/packages/llvm-linux-arm64-musl/package.json index a9288c2ca..8b3b2f185 100644 --- a/packages/llvm-linux-arm64-musl/package.json +++ b/packages/llvm-linux-arm64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/llvm-linux-arm64-musl", - "version": "0.4.3", + "version": "0.4.4", "description": "Statically linked LLVM code-generation helper for scriptc on Linux arm64 musl", "license": "Apache-2.0 WITH LLVM-exception", "homepage": "https://scriptc.dev", diff --git a/packages/llvm-linux-x64-gnu/package.json b/packages/llvm-linux-x64-gnu/package.json index c55f51847..79b7eba3f 100644 --- a/packages/llvm-linux-x64-gnu/package.json +++ b/packages/llvm-linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/llvm-linux-x64-gnu", - "version": "0.4.3", + "version": "0.4.4", "description": "Pinned LLVM code-generation helper for scriptc on Linux x64", "license": "Apache-2.0 WITH LLVM-exception", "homepage": "https://scriptc.dev", diff --git a/packages/llvm-linux-x64-musl/package.json b/packages/llvm-linux-x64-musl/package.json index b257085bf..5bffa5bef 100644 --- a/packages/llvm-linux-x64-musl/package.json +++ b/packages/llvm-linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/llvm-linux-x64-musl", - "version": "0.4.3", + "version": "0.4.4", "description": "Statically linked LLVM code-generation helper for scriptc on Linux x64 musl", "license": "Apache-2.0 WITH LLVM-exception", "homepage": "https://scriptc.dev", diff --git a/packages/llvm-win32-x64-msvc/package.json b/packages/llvm-win32-x64-msvc/package.json index 0f3f99331..14c747a4a 100644 --- a/packages/llvm-win32-x64-msvc/package.json +++ b/packages/llvm-win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/llvm-win32-x64-msvc", - "version": "0.4.3", + "version": "0.4.4", "description": "Pinned LLVM code-generation helper for scriptc on Windows x64", "license": "Apache-2.0 WITH LLVM-exception", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-android-arm64/package.json b/packages/runtime-android-arm64/package.json index 392ef1717..1dfa1b177 100644 --- a/packages/runtime-android-arm64/package.json +++ b/packages/runtime-android-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-android-arm64", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc library runtime pack for Android arm64", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-darwin-arm64/package.json b/packages/runtime-darwin-arm64/package.json index 354526024..32463357f 100644 --- a/packages/runtime-darwin-arm64/package.json +++ b/packages/runtime-darwin-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-darwin-arm64", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc runtime pack for macOS arm64", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-darwin-arm64/runtime-pack-matrix.mjs b/packages/runtime-darwin-arm64/runtime-pack-matrix.mjs index 7b2d3e115..197adc516 100644 --- a/packages/runtime-darwin-arm64/runtime-pack-matrix.mjs +++ b/packages/runtime-darwin-arm64/runtime-pack-matrix.mjs @@ -14,6 +14,7 @@ import { */ const any = (...features) => ({ any: features }); +const all = (...features) => ({ all: features }); // ld64 dead-strips Mach-O symbol subsections without an ELF-style compile // flag. Keep this checked-in metadata alongside the matrix so pack build and @@ -43,6 +44,7 @@ export const RUNTIME_PACK_MATRIX = withLibraryRuntimeFlavors( { id: "quickjs", predicate: false }, { id: "libregexp", predicate: "regex" }, { id: "zlib", predicate: "zlibEffective" }, + { id: "brotli", predicate: all("zlib", "brotli") }, { id: "mbedtls", predicate: any("tlsEffective", "cipher", "ecdh", "dh", "pki") }, ], system_libraries: [{ name: "System", predicate: true }], diff --git a/packages/runtime-darwin-arm64/scripts/build.mjs b/packages/runtime-darwin-arm64/scripts/build.mjs index e492c36b4..b6b855c05 100644 --- a/packages/runtime-darwin-arm64/scripts/build.mjs +++ b/packages/runtime-darwin-arm64/scripts/build.mjs @@ -72,6 +72,7 @@ async function build() { const quickjs = join(vendorRoot, "quickjs-ng"); const zlib = join(vendorRoot, "zlib"); const mbedtls = join(vendorRoot, "mbedtls"); + const brotli = join(vendorRoot, "brotli", "c"); const QJS_SOURCES = ["dtoa.c", "libregexp.c", "libunicode.c", "quickjs.c"]; const LRE_SOURCES = ["libregexp.c", "libunicode.c"]; const ZLIB_SOURCES = [ @@ -112,20 +113,23 @@ async function build() { return parallelMap(items, width, task); } + // Archive members are named by basename, so a source in a subdirectory + // (brotli's dec/ and enc/ share file names) is named after its path. + const objectName = (source) => source.replaceAll("/", "-").replace(/\.c$/, ".o"); async function archive(id, sources, sourceRoot, flags) { const root = join(stagedOutputRoot, "vendor", id); const objectRoot = join(root, "objects"); await parallel(sources, async (source) => { await compile( join(sourceRoot, source), - join(objectRoot, source.replace(/\.c$/, ".o")), + join(objectRoot, objectName(source)), unalignedVendorSources.has(source) ? flags.filter((flag) => !codeAlignment.includes(flag)) : flags, ); }); const output = join(root, `libscriptc-${id}.a`); - const objects = sources.map((source) => join(objectRoot, source.replace(/\.c$/, ".o"))); + const objects = sources.map((source) => join(objectRoot, objectName(source))); await createDeterministicArchive(archiver, output, objects); await rm(objectRoot, { recursive: true, force: true }); return { @@ -181,6 +185,7 @@ async function build() { ...(unit.source === "scr_zlib.c" || unit.source === "scr_fetch.c" ? ["-I", zlib] : []), + ...(unit.source === "scr_brotli.c" ? ["-I", join(brotli, "include")] : []), ]; const unitFlags = [ ...commonFlags, @@ -268,6 +273,17 @@ async function build() { const mbedtlsSources = (await readdir(join(mbedtls, "library"))) .filter((name) => !name.startsWith(".") && name.endsWith(".c")) .sort(); + const brotliSources = ( + await Promise.all( + ["common", "dec", "enc"].map(async (dir) => + (await readdir(join(brotli, dir))) + .filter((name) => !name.startsWith(".") && name.endsWith(".c")) + .map((name) => `${dir}/${name}`), + ), + ) + ) + .flat() + .sort(); const archives = [ await archive("quickjs", QJS_SOURCES, quickjs, [ "-target", @@ -301,6 +317,15 @@ async function build() { "-I", zlib, ]), + await archive("brotli", brotliSources, brotli, [ + "-target", + RUNTIME_PACK_MATRIX.target.llvm_triple, + "-std=c11", + "-Os", + ...codeAlignment, + "-I", + join(brotli, "include"), + ]), await archive("mbedtls", mbedtlsSources, join(mbedtls, "library"), [ "-target", RUNTIME_PACK_MATRIX.target.llvm_triple, @@ -325,6 +350,7 @@ async function build() { ], [join(vendorRoot, "unicode", "LICENSE"), "artifacts/licenses/unicode.txt", "Unicode-3.0"], [join(zlib, "LICENSE"), "artifacts/licenses/zlib.txt", "Zlib"], + [join(vendorRoot, "brotli", "LICENSE"), "artifacts/licenses/brotli.txt", "MIT"], [join(mbedtls, "LICENSE"), "artifacts/licenses/mbedtls.txt", "Apache-2.0"], ]; await Promise.all( diff --git a/packages/runtime-darwin-x64/package.json b/packages/runtime-darwin-x64/package.json index 58aa358b2..c0577b04c 100644 --- a/packages/runtime-darwin-x64/package.json +++ b/packages/runtime-darwin-x64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-darwin-x64", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc runtime pack for macOS x64", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-ios-arm64/package.json b/packages/runtime-ios-arm64/package.json index 6193c5258..9c2134280 100644 --- a/packages/runtime-ios-arm64/package.json +++ b/packages/runtime-ios-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-ios-arm64", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc library runtime pack for iOS arm64", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-ios-simulator-arm64/package.json b/packages/runtime-ios-simulator-arm64/package.json index 7d01c45d3..6b7563a6a 100644 --- a/packages/runtime-ios-simulator-arm64/package.json +++ b/packages/runtime-ios-simulator-arm64/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-ios-simulator-arm64", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc library runtime pack for iOS simulator arm64", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-linux-arm64-gnu/package.json b/packages/runtime-linux-arm64-gnu/package.json index 419080c3a..f0ae56929 100644 --- a/packages/runtime-linux-arm64-gnu/package.json +++ b/packages/runtime-linux-arm64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-linux-arm64-gnu", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc runtime pack for Linux arm64 glibc", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-linux-arm64-musl/package.json b/packages/runtime-linux-arm64-musl/package.json index 2bae09884..79fa8e7dd 100644 --- a/packages/runtime-linux-arm64-musl/package.json +++ b/packages/runtime-linux-arm64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-linux-arm64-musl", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc runtime pack for Linux arm64 musl", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-linux-x64-gnu/package.json b/packages/runtime-linux-x64-gnu/package.json index 6749ddeea..45af8d2b7 100644 --- a/packages/runtime-linux-x64-gnu/package.json +++ b/packages/runtime-linux-x64-gnu/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-linux-x64-gnu", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc runtime pack for Linux x64 glibc", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-linux-x64-musl/package.json b/packages/runtime-linux-x64-musl/package.json index 9b4803406..fe9d11bcd 100644 --- a/packages/runtime-linux-x64-musl/package.json +++ b/packages/runtime-linux-x64-musl/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-linux-x64-musl", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc runtime pack for Linux x64 musl", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-pack-common/runtime-pack-matrix.mjs b/packages/runtime-pack-common/runtime-pack-matrix.mjs index 2c02b55c3..a7590fcc5 100644 --- a/packages/runtime-pack-common/runtime-pack-matrix.mjs +++ b/packages/runtime-pack-common/runtime-pack-matrix.mjs @@ -83,6 +83,7 @@ export const OPTIONAL_RUNTIME_SOURCES = [ // Blob and File box their reads as dyn promises through scr_async_dyn.c. ["scr_blob.c", "dynAsync"], ["scr_zlib.c", "zlib"], + ["scr_brotli.c", all("zlib", "brotli")], ["scr_events.c", "events"], ["scr_readline.c", "events"], ["scr_readline_tty.c", all("events", "regex")], @@ -230,6 +231,7 @@ export function createRuntimePackMatrix({ { id: "quickjs", predicate: false }, { id: "libregexp", predicate: "regex" }, { id: "zlib", predicate: "zlibEffective" }, + { id: "brotli", predicate: all("zlib", "brotli") }, { id: "mbedtls", predicate: any("tlsEffective", "cipher", "ecdh", "dh", "pki") }, ]; const matrix = withLibraryRuntimeFlavors( diff --git a/packages/runtime-pack-common/scripts/build.mjs b/packages/runtime-pack-common/scripts/build.mjs index e22f2a37c..d4794b7d1 100644 --- a/packages/runtime-pack-common/scripts/build.mjs +++ b/packages/runtime-pack-common/scripts/build.mjs @@ -85,6 +85,7 @@ async function build() { const quickjs = join(vendorRoot, "quickjs-ng"); const zlib = join(vendorRoot, "zlib"); const mbedtls = join(vendorRoot, "mbedtls"); + const brotli = join(vendorRoot, "brotli", "c"); const qjsSources = ["dtoa.c", "libregexp.c", "libunicode.c", "quickjs.c"]; const lreSources = ["libregexp.c", "libunicode.c"]; const zlibSources = [ @@ -131,6 +132,9 @@ async function build() { const width = Math.max(1, Math.min(8, availableParallelism())); return parallelMap(items, width, task); }; + // Archive members are named by basename, so a source in a subdirectory + // (brotli's dec/ and enc/ share file names) is named after its path. + const objectName = (source) => source.replaceAll("/", "-").replace(/\.c$/, ".o"); const archive = async (id, sources, sourceRoot, flags) => { process.stdout.write(`building ${packageManifest.name} ${id} archive\n`); const root = join(stagedOutputRoot, "vendor", id); @@ -138,7 +142,7 @@ async function build() { await parallel(sources, async (source) => compile( join(sourceRoot, source), - join(objectRoot, source.replace(/\.c$/, ".o")), + join(objectRoot, objectName(source)), unalignedVendorSources.has(source) ? flags.filter((flag) => !codeAlignment.includes(flag)) : flags, @@ -148,7 +152,7 @@ async function build() { await createDeterministicArchive( archiver, output, - sources.map((source) => join(objectRoot, source.replace(/\.c$/, ".o"))), + sources.map((source) => join(objectRoot, objectName(source))), archiverArgs, ); await rm(objectRoot, { recursive: true, force: true }); @@ -232,6 +236,7 @@ async function build() { ...(unit.source === "scr_zlib.c" || unit.source === "scr_fetch.c" ? ["-I", zlib] : []), + ...(unit.source === "scr_brotli.c" ? ["-I", join(brotli, "include")] : []), ]; // Worker variants link only into executables, whose own TLS block // holds every runtime thread-local: on ELF the initial-exec model @@ -334,6 +339,17 @@ async function build() { const mbedtlsSources = (await readdir(join(mbedtls, "library"))) .filter((name) => !name.startsWith(".") && name.endsWith(".c")) .sort(); + const brotliSources = ( + await Promise.all( + ["common", "dec", "enc"].map(async (dir) => + (await readdir(join(brotli, dir))) + .filter((name) => !name.startsWith(".") && name.endsWith(".c")) + .map((name) => `${dir}/${name}`), + ), + ) + ) + .flat() + .sort(); // Vendored QuickJS reads `clock_gettime` for its monotonic clock. WASI // exposes that declaration only when its process-clock emulation ABI is // selected, so vendor sources inherit the target's runtime defines too. @@ -388,6 +404,17 @@ async function build() { ]), ] : []), + ...(requestedArchives.has("brotli") + ? [ + await archive("brotli", brotliSources, brotli, [ + ...vendorTarget, + "-std=c11", + "-Os", + "-I", + join(brotli, "include"), + ]), + ] + : []), ...(requestedArchives.has("mbedtls") ? [ await archive("mbedtls", mbedtlsSources, join(mbedtls, "library"), [ @@ -417,6 +444,7 @@ async function build() { "BSD-3-Clause", ], [join(zlib, "LICENSE"), "artifacts/licenses/zlib.txt", "Zlib"], + [join(vendorRoot, "brotli", "LICENSE"), "artifacts/licenses/brotli.txt", "MIT"], [join(mbedtls, "LICENSE"), "artifacts/licenses/mbedtls.txt", "Apache-2.0"], ]; licensed.push([ diff --git a/packages/runtime-wasm32-wasi/package.json b/packages/runtime-wasm32-wasi/package.json index 63a95601d..ac2f4a5e9 100644 --- a/packages/runtime-wasm32-wasi/package.json +++ b/packages/runtime-wasm32-wasi/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-wasm32-wasi", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc runtime pack for WASI Preview 1", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime-win32-x64-msvc/package.json b/packages/runtime-win32-x64-msvc/package.json index 01bec7c31..9a5731da2 100644 --- a/packages/runtime-win32-x64-msvc/package.json +++ b/packages/runtime-win32-x64-msvc/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime-win32-x64-msvc", - "version": "0.4.3", + "version": "0.4.4", "description": "Precompiled scriptc runtime pack for Windows x64 MSVC", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime/package.json b/packages/runtime/package.json index d367ad6bf..1d58b00e5 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/runtime", - "version": "0.4.3", + "version": "0.4.4", "description": "scriptc native runtime sources and vendored dependencies", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/runtime/src/scr_brotli.c b/packages/runtime/src/scr_brotli.c new file mode 100644 index 000000000..f66ecae75 --- /dev/null +++ b/packages/runtime/src/scr_brotli.c @@ -0,0 +1,323 @@ +/* node:zlib's Brotli codec over the vendored brotli 1.2.0 (the version Node + * v24.22.0 bundles, so compressed bytes match Node's). Node's + * BrotliEncoderContext and BrotliDecoderContext (src/node_zlib.cc) plug into + * scr_zlib.c's engine as a codec, so the one-shot, callback, promise and + * stream forms run exactly as their zlib counterparts do. The option ladder + * is lib/zlib.js's Brotli() followed by ZlibBase(). Linked only when the + * program uses Brotli; scr_brotli_install, which %main calls first, + * connects it to scr_zlib.c. */ +#include "scr_runtime.h" + +#include +#include +#include +#include +#include +#include + +enum { SCR_BROTLI_DECODE = 8, SCR_BROTLI_ENCODE = 9 }; +/* kMaxBrotliParam + 1: the largest BROTLI_PARAM_* value is + * BROTLI_PARAM_NDIRECT (8). An unset slot holds 0xFFFFFFFF, as Node's + * Uint32Array filled with -1 does. */ +#define SCR_BROTLI_PARAMS 9 +#define SCR_BROTLI_UNSET 0xFFFFFFFFu + +typedef struct { + bool encode; + BrotliEncoderState *enc; + BrotliEncoderPreparedDictionary *prepared; + BrotliDecoderState *dec; + /* The dictionary stays alive while the encoder's prepared dictionary or + * the decoder holds it. */ + unsigned char *dict; + size_t dict_len; + int flush; + bool enc_ok; + BrotliDecoderResult dec_result; + BrotliDecoderErrorCode dec_error; + char dec_code[64]; +} ScrBrotli; + +static void scr_brotli_oom(void) { + scr_trap("scriptc: out of memory\n"); +} + +static bool scr_brotli_fail(ScrZlibError *out, const char *message, const char *code, int err) { + out->message = message; + out->code = code; + out->err = err; + return true; +} + +static void scr_brotli_close(ScrBrotli *b) { + if (b->enc) BrotliEncoderDestroyInstance(b->enc); + if (b->prepared) BrotliEncoderDestroyPreparedDictionary(b->prepared); + if (b->dec) BrotliDecoderDestroyInstance(b->dec); + b->enc = NULL; + b->prepared = NULL; + b->dec = NULL; +} + +/* Init(dictionary): a fresh instance with the dictionary attached. As in + * Node, the decoder's last error survives a re-initialization. True with + * *out filled on failure. */ +static bool scr_brotli_init(ScrBrotli *b, ScrZlibError *out) { + scr_brotli_close(b); + if (b->encode) { + b->enc = BrotliEncoderCreateInstance(NULL, NULL, NULL); + b->enc_ok = false; + if (!b->enc) return scr_brotli_fail(out, "Could not initialize Brotli instance", "ERR_ZLIB_INITIALIZATION_FAILED", -1); + if (b->dict_len == 0) return false; + b->prepared = BrotliEncoderPrepareDictionary(BROTLI_SHARED_DICTIONARY_RAW, b->dict_len, b->dict, BROTLI_MAX_QUALITY, + NULL, NULL, NULL); + if (!b->prepared) return scr_brotli_fail(out, "Failed to prepare brotli dictionary", "ERR_ZLIB_DICTIONARY_LOAD_FAILED", -1); + if (!BrotliEncoderAttachPreparedDictionary(b->enc, b->prepared)) + return scr_brotli_fail(out, "Failed to attach brotli dictionary", "ERR_ZLIB_DICTIONARY_LOAD_FAILED", -1); + return false; + } + b->dec = BrotliDecoderCreateInstance(NULL, NULL, NULL); + if (!b->dec) return scr_brotli_fail(out, "Could not initialize Brotli instance", "ERR_ZLIB_INITIALIZATION_FAILED", -1); + if (b->dict_len != 0 && !BrotliDecoderAttachDictionary(b->dec, BROTLI_SHARED_DICTIONARY_RAW, b->dict_len, b->dict)) + return scr_brotli_fail(out, "Failed to attach brotli dictionary", "ERR_ZLIB_DICTIONARY_LOAD_FAILED", -1); + return false; +} + +static void scr_brotli_free(void *state) { + ScrBrotli *b = state; + if (!b) return; + scr_brotli_close(b); + free(b->dict); + free(b); +} + +/* DoThreadPoolWork: runs on a worker thread and touches only the state. */ +static void scr_brotli_work(void *state, int flush, const unsigned char *in, uint32_t in_len, unsigned char *out, + uint32_t out_len, uint32_t *avail_in, uint32_t *avail_out) { + ScrBrotli *b = state; + size_t in_left = in_len, out_left = out_len; + const uint8_t *next_in = in; + uint8_t *next_out = out; + b->flush = flush; + if (b->encode) { + b->enc_ok = BrotliEncoderCompressStream(b->enc, (BrotliEncoderOperation)flush, &in_left, &next_in, &out_left, + &next_out, NULL) != BROTLI_FALSE; + } else { + b->dec_result = BrotliDecoderDecompressStream(b->dec, &in_left, &next_in, &out_left, &next_out, NULL); + if (b->dec_result == BROTLI_DECODER_RESULT_ERROR) { + b->dec_error = BrotliDecoderGetErrorCode(b->dec); + snprintf(b->dec_code, sizeof b->dec_code, "ERR_%s", BrotliDecoderErrorString(b->dec_error)); + } + } + *avail_in = (uint32_t)in_left; + *avail_out = (uint32_t)out_left; +} + +/* GetErrorInfo. */ +static bool scr_brotli_error(const void *state, ScrZlibError *out) { + const ScrBrotli *b = state; + if (b->encode) { + if (!b->enc_ok) return scr_brotli_fail(out, "Compression failed", "ERR_BROTLI_COMPRESSION_FAILED", -1); + return false; + } + if (b->dec_error != BROTLI_DECODER_NO_ERROR) + return scr_brotli_fail(out, "Decompression failed", b->dec_code, (int)b->dec_error); + /* zlib's answer for a truncated stream; Brotli has no code of its own. */ + if (b->flush == BROTLI_OPERATION_FINISH && b->dec_result == BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT) + return scr_brotli_fail(out, "unexpected end of file", "Z_BUF_ERROR", -5); + return false; +} + +/* ResetStream is Init() without a dictionary: as in Node, the reset + * instance drops the dictionary and the parameters. */ +static bool scr_brotli_reset(void *state, ScrZlibError *out) { + ScrBrotli *b = state; + free(b->dict); + b->dict = NULL; + b->dict_len = 0; + return scr_brotli_init(b, out); +} + +static const ScrZlibCodec scr_brotli_codec = { + scr_brotli_work, + scr_brotli_error, + scr_brotli_reset, + scr_brotli_free, +}; + +/* ── lib/zlib.js Brotli() ──────────────────────────────────────────── */ + +static const ScrDyn *scr_brotli_opt(const ScrDyn *opts, const char *key) { + if (opts == NULL || opts->kind != SCR_DYN_OBJ) return NULL; + return scr_dyn_obj_get((ScrDyn *)opts, key, strlen(key)); +} + +/* Uint32Array element assignment: ToUint32 of a number or boolean. */ +static uint32_t scr_brotli_uint32(const ScrDyn *v) { + if (v->kind == SCR_DYN_BOOL) return v->v.b ? 1 : 0; + double d = v->v.num; + if (!isfinite(d)) return 0; + double m = fmod(trunc(d), 4294967296.0); + if (m < 0) m += 4294967296.0; + return (uint32_t)m; +} + +/* ERR_BROTLI_INVALID_PARAM: the whole key, then Node's text. */ +static void scr_brotli_invalid_param(const ScrStr *key) { + static const char suffix[] = " is not a valid Brotli parameter"; + size_t len = key->len + sizeof suffix - 1; + char *message = malloc(len); + if (!message) scr_brotli_oom(); + memcpy(message, key->data, key->len); + memcpy(message + key->len, suffix, sizeof suffix - 1); + scr_throw_error_msg_code(SCR_ERR_RANGE, message, len, "ERR_BROTLI_INVALID_PARAM"); + free(message); +} + +/* opts.params: each own key must name a parameter (0..8) once, and each + * value must be a number or boolean. */ +static bool scr_brotli_params(const ScrDyn *params, uint32_t values[SCR_BROTLI_PARAMS]) { + for (size_t i = 0; i < SCR_BROTLI_PARAMS; i++) values[i] = SCR_BROTLI_UNSET; + if (params == NULL || !scr_dyn_truthy(params)) return true; + ScrDyn *view = params->kind == SCR_DYN_TYPED_REF ? scr_dyn_typed_ref_materialize(params) : NULL; + if (scr_exc_pending()) return false; + const ScrDyn *p = view ? view : params; + if (p->kind == SCR_DYN_STR) { + /* Object.keys of a string names its indices; the first value is a + * one-character string, which the type check rejects. */ + ScrStr *first = scr_str_new(p->v.str->data, 1); + ScrDyn *value = scr_dyn_new_str(first); + scr_str_release(first); + scr_dyn_prop_type_fail("options.params[key]", "of type number", value); + scr_dyn_release(value); + scr_dyn_release(view); + return false; + } + if (p->kind != SCR_DYN_OBJ && p->kind != SCR_DYN_ARR) { + scr_dyn_release(view); + return true; + } + ScrDyn *keys = scr_dyn_own_keys(p); + bool ok = keys != NULL; + size_t count = ok && keys->kind == SCR_DYN_ARR ? keys->v.arr.len : 0; + for (size_t i = 0; ok && i < count; i++) { + const ScrDyn *key = keys->v.arr.items[i]; + if (key->kind != SCR_DYN_STR) continue; + double index = NAN; + if (!scr_dyn_number_coerce_js(key, &index)) { + ok = false; + break; + } + if (isnan(index) || index < 0 || index > SCR_BROTLI_PARAMS - 1 || trunc(index) != index || + values[(int)index] != SCR_BROTLI_UNSET) { + scr_brotli_invalid_param(key->v.str); + ok = false; + break; + } + ScrDyn *value = scr_dyn_obj_read(p, key->v.str->data, key->v.str->len); + if (!value) { + ok = false; + break; + } + if (value->kind != SCR_DYN_NUM && value->kind != SCR_DYN_BOOL) { + scr_dyn_prop_type_fail("options.params[key]", "of type number", value); + scr_dyn_release(value); + ok = false; + break; + } + values[(int)index] = scr_brotli_uint32(value); + scr_dyn_release(value); + } + scr_dyn_release(keys); + scr_dyn_release(view); + return ok; +} + +/* opts.dictionary: an ArrayBufferView, or an ArrayBuffer read as a Buffer. + * A copy (or NULL for none) in *dict. */ +static bool scr_brotli_dictionary(const ScrDyn *d, unsigned char **dict, size_t *dict_len) { + *dict = NULL; + *dict_len = 0; + if (d == NULL || d->kind == SCR_DYN_UNDEF) return true; + ScrBytes *bytes = NULL; + if (d->kind == SCR_DYN_BYTES) { + bytes = scr_bytes_raw_view(d->v.bytes); + } else if (scr_buffer_storage_is(d)) { + bytes = scr_array_buffer_view(SCR_BYTES_U8, (ScrDyn *)d, scr_dyn_undefined(), scr_dyn_undefined()); + if (!bytes) return false; + } else { + scr_dyn_prop_type_fail("options.dictionary", "an instance of Buffer, TypedArray, DataView, or ArrayBuffer", d); + return false; + } + if (bytes->len) { + *dict = malloc(bytes->len); + if (!*dict) scr_brotli_oom(); + memcpy(*dict, bytes->data, bytes->len); + *dict_len = bytes->len; + } + scr_bytes_release(bytes); + return true; +} + +static void scr_brotli_init_failed(void) { + static const char message[] = "Initialization failed"; + scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "ERR_ZLIB_INITIALIZATION_FAILED"); +} + +static bool scr_brotli_options_object(int mode, const ScrDyn *opts, ScrZlibOptions *out) { + memset(out, 0, sizeof *out); + out->chunk_size = 16384; + out->flush = BROTLI_OPERATION_PROCESS; + out->finish_flush = BROTLI_OPERATION_FINISH; + out->max_output = 9007199254740991.0; + uint32_t params[SCR_BROTLI_PARAMS]; + if (!scr_brotli_params(scr_brotli_opt(opts, "params"), params)) return false; + unsigned char *dict; + size_t dict_len; + if (!scr_brotli_dictionary(scr_brotli_opt(opts, "dictionary"), &dict, &dict_len)) return false; + ScrBrotli *b = calloc(1, sizeof *b); + if (!b) scr_brotli_oom(); + b->encode = mode == SCR_BROTLI_ENCODE; + b->dict = dict; + b->dict_len = dict_len; + ScrZlibError err; + bool failed = scr_brotli_init(b, &err); + for (int i = 0; !failed && i < SCR_BROTLI_PARAMS; i++) { + if (params[i] == SCR_BROTLI_UNSET) continue; + failed = b->encode ? !BrotliEncoderSetParameter(b->enc, (BrotliEncoderParameter)i, params[i]) + : !BrotliDecoderSetParameter(b->dec, (BrotliDecoderParameter)i, params[i]); + } + if (failed) { + scr_brotli_free(b); + scr_brotli_init_failed(); + return false; + } + out->codec_state = b; + out->codec_state_free = scr_brotli_free; + /* ZlibBase's `if (opts)`: a falsy value reads no more options. */ + if (opts == NULL || !scr_dyn_truthy(opts)) return true; + return scr_zlib_base_options(opts, BROTLI_OPERATION_EMIT_METADATA, out); +} + +/* A typed options object is read through its materialized view. */ +static bool scr_brotli_options(int mode, const ScrDyn *opts, ScrZlibOptions *out) { + if (opts == NULL || opts->kind != SCR_DYN_TYPED_REF) return scr_brotli_options_object(mode, opts, out); + ScrDyn *view = scr_dyn_typed_ref_materialize(opts); + bool ok = false; + if (scr_exc_pending()) memset(out, 0, sizeof *out); + else ok = scr_brotli_options_object(mode, view, out); + scr_dyn_release(view); + return ok; +} + +/* Moves the prepared instance out of the options. */ +static ScrZlibEngine *scr_brotli_engine(int mode, ScrZlibOptions *o) { + ScrBrotli *b = o->codec_state; + o->codec_state = NULL; + return scr_zlib_engine_codec(mode, &scr_brotli_codec, b, o->reject_garbage); +} + +static const ScrZlibBrotliHooks scr_brotli_hooks = {scr_brotli_options, scr_brotli_engine}; + +void scr_brotli_install(void) { + scr_zlib_brotli_hooks = &scr_brotli_hooks; +} diff --git a/packages/runtime/src/scr_bytes.c b/packages/runtime/src/scr_bytes.c index 907c177dc..3926bf83e 100644 --- a/packages/runtime/src/scr_bytes.c +++ b/packages/runtime/src/scr_bytes.c @@ -874,6 +874,21 @@ ScrBytes *scr_bytes_from_dyn(ScrBytesElem elem, const ScrDyn *value, bool from) // Constructors drain array iterators before element coercion. Node's .from // fast path reads ordinary array elements during conversion instead. Strings // supplied to .from iterate by code point (set reads UTF-16 code units). + // An object with a Symbol.iterator method iterates; others are array-like. + ScrDyn *method = scr_dyn_iterator_method(value); + if (method) { + ScrDyn *items = scr_dyn_iterate_with(value, method); + scr_dyn_release(method); + if (!items) return NULL; + ScrBytes *out = scr_bytes_new(elem, (double)items->v.arr.len); + if (out && !scr_bytes_copy_array_like(out, items, 0, out->len)) { + scr_bytes_release(out); + out = NULL; + } + scr_dyn_release(items); + return out; + } + if (scr_exc_pending()) return NULL; if ((!from && value->kind == SCR_DYN_ARR) || (from && value->kind == SCR_DYN_STR)) { ScrDyn *items = scr_dyn_iter_pack(value, NULL); if (!items) return NULL; @@ -3314,6 +3329,55 @@ double scr_bytes_index_of_num(const ScrBytes *b, double v, double off, bool fwd) return scr_bytes_index_of(b, &needle, off, 1, fwd); } +/* The first index a TypedArray search from `from` starts at + * (ToIntegerOrInfinity, then relative to the end when negative), or false + * when it starts past the last element. */ +static bool scr_bytes_search_start(size_t len, double from, size_t *start) { + double n = from != from ? 0 : trunc(from); + if (n >= (double)len) return false; + if (n < 0) n = n + (double)len < 0 ? 0 : n + (double)len; + *start = (size_t)n; + return true; +} + +double scr_bytes_index_of_elem(const ScrBytes *b, double x, double from, bool last) { + /* A Buffer viewed as a Uint8Array keeps Buffer's own search: the needle + * is taken as a byte, and a NaN byteOffset searches the whole buffer. */ + if (scr_bytes_is_buffer(b)) return scr_bytes_index_of_num(b, x, from, !last); + SCR_BYTES_SNAPSHOT(b); + size_t len = b->len; + size_t size = scr_bytes_elem_size(b->elem); + if (len == 0 || x != x) return -1; + if (!last) { + size_t k; + if (!scr_bytes_search_start(len, from, &k)) return -1; + for (; k < len; k++) + if (scr_bytes_decode(b->elem, b->data + k * size) == x) return (double)k; + return -1; + } + double n = from != from ? 0 : trunc(from); + double k = n >= 0 ? (n < (double)len - 1 ? n : (double)len - 1) : (double)len + n; + if (k < 0) return -1; + for (size_t i = (size_t)k + 1; i-- > 0;) + if (scr_bytes_decode(b->elem, b->data + i * size) == x) return (double)i; + return -1; +} + +bool scr_bytes_includes_elem(const ScrBytes *b, double x, double from) { + if (scr_bytes_is_buffer(b)) return scr_bytes_index_of_num(b, x, from, true) >= 0; + SCR_BYTES_SNAPSHOT(b); + size_t len = b->len; + size_t size = scr_bytes_elem_size(b->elem); + size_t k; + if (len == 0 || !scr_bytes_search_start(len, from, &k)) return false; + bool nan = x != x; + for (; k < len; k++) { + double v = scr_bytes_decode(b->elem, b->data + k * size); + if (v == x || (nan && v != v)) return true; + } + return false; +} + /* fill's shared core over a normalized byte pattern. nargs counts the * present offset/end args. An EMPTY pattern zero-fills when zero_ok * (Node's '' string) and is the constant TypeError otherwise (an empty diff --git a/packages/runtime/src/scr_bytes.h b/packages/runtime/src/scr_bytes.h index f3e36f9ad..7c0a935cc 100644 --- a/packages/runtime/src/scr_bytes.h +++ b/packages/runtime/src/scr_bytes.h @@ -538,6 +538,16 @@ ScrEmitter *scr_emitter_set_max_chk(ScrEmitter *em, const ScrDyn *n); void scr_emitter_set_default_max_chk(const ScrDyn *n, const ScrStr *name); double scr_bytes_index_of(const ScrBytes *b, const ScrBytes *needle, double off, double align, bool fwd); double scr_bytes_index_of_num(const ScrBytes *b, double v, double off, bool fwd); +/* TypedArray indexOf (last false) and lastIndexOf (last true) over any + * element kind, with strict equality: NaN is never found and -0 matches 0. + * `from` is the fromIndex argument (ToIntegerOrInfinity applies); the + * caller passes 0, or +Infinity for lastIndexOf, when it is omitted. A + * Buffer (a Uint8Array receiver can be one) searches as Buffer's + * indexOf and lastIndexOf do. */ +double scr_bytes_index_of_elem(const ScrBytes *b, double x, double from, bool last); +/* TypedArray includes: indexOf's search from `from` with SameValueZero, + * so NaN is found. A Buffer searches as Buffer's includes does. */ +bool scr_bytes_includes_elem(const ScrBytes *b, double x, double from); ScrBytes *scr_bytes_fill(ScrBytes *b, const ScrBytes *pattern, double nargs, double offset, double end); ScrBytes *scr_bytes_fill_num(ScrBytes *b, double v, double nargs, double offset, double end); ScrBytes *scr_bytes_fill_str(ScrBytes *b, const ScrStr *s, const ScrStr *enc, diff --git a/packages/runtime/src/scr_bytes_io.c b/packages/runtime/src/scr_bytes_io.c index 72053a6ab..253cad1da 100644 --- a/packages/runtime/src/scr_bytes_io.c +++ b/packages/runtime/src/scr_bytes_io.c @@ -59,6 +59,10 @@ static bool scr_fs_read_utf8(ScrStr *encoding) { return encoding->len == 0 || scr_bytes_encoding_is_utf8(encoding); } +void scr_fs_check_read_encoding(ScrStr *encoding) { + (void)scr_fs_read_encoding_valid(encoding); +} + ScrStr *scr_fs_read_file_encoded(ScrStr *path, ScrStr *encoding) { if (!scr_fs_read_encoding_valid(encoding)) return NULL; if (scr_fs_read_utf8(encoding)) return scr_fs_read_file(path); diff --git a/packages/runtime/src/scr_dyn.h b/packages/runtime/src/scr_dyn.h index 60fdf301d..257aa6444 100644 --- a/packages/runtime/src/scr_dyn.h +++ b/packages/runtime/src/scr_dyn.h @@ -872,6 +872,10 @@ ScrDyn *scr_dyn_symbol_ref(ScrSym *value, void (*release)(ScrSym *), ScrStr *(*r ScrDyn *scr_dyn_new_str(ScrStr *s); ScrDyn *scr_dyn_new_arr(void); ScrDyn *scr_dyn_array_constructor(void); +/* Gives a builtin constructor value (Object, Array, Error) its builtin + * `prototype`: non-writable, non-enumerable, non-configurable. Takes the + * prototype. */ +void scr_dyn_fn_seed_prototype(ScrDyn *function, ScrDyn *prototype); /* The interned builtin constructor `name` (Object, Date, RegExp, Map, Set, * Promise, WeakMap, WeakSet) as a dynamic function value: +1. */ ScrDyn *scr_dyn_global_constructor(const ScrStr *name); @@ -1330,6 +1334,11 @@ ScrDyn *scr_dyn_from_error(const ScrError *e); void scr_error_register_dyn(const ScrVt *vt, ScrDyn *(*box)(void *)); ScrDyn *scr_error_dyn_fields(const ScrError *e); void scr_error_dyn_place_name(ScrDyn *view, const char *after, size_t after_len); +/* An Error subclass view of an instance whose class keeps a property bag: + * `name` and `message` take their committed positions, and data values + * from the slots (scr_json.c). `name_placed`: the class's construction sets + * `name`, and the view already has it in place. */ +void scr_error_dyn_follow_bag(ScrDyn *view, const ScrDyn *bag, const ScrError *e, bool name_placed); /* An accessor property of a fresh object: enumerable and configurable, * with the given getter and setter (either may be NULL). Moves both. */ void scr_dyn_obj_set_accessor(ScrDyn *obj, const char *key, size_t key_len, ScrDyn *getter, ScrDyn *setter); @@ -1384,6 +1393,16 @@ ScrDyn *scr_dyn_invoke_buffer_to_string(ScrDyn *recv, ScrDyn *callee, const char ScrDyn *scr_dyn_invoke_buffer_search(ScrDyn *recv, ScrDyn *callee, const char *method, int32_t *mid_slot, ScrDyn *const *args, size_t argc, const char *what); ScrDyn *scr_dyn_invoke_buffer(ScrDyn *recv, ScrDyn *callee, const char *method, int32_t *mid_slot, ScrDyn *const *args, size_t argc, const char *what); ScrDyn *scr_dyn_invoke(ScrDyn *recv, const char *method, ScrDyn *const *args, size_t argc, const char *what); +/* A %TypedArray%.prototype method called on a checked typed array (not a + * DataView): its answer (+1, or NULL with the exception pending), with + * *handled false for a name it does not implement. */ +ScrDyn *scr_dyn_bytes_method(ScrDyn *recv, const char *method, ScrDyn *const *args, size_t argc, bool *handled); +/* A plain object's Symbol.iterator method (+1), read once; NULL when it + * has none, or with the exception pending from its getter. */ +ScrDyn *scr_dyn_iterator_method(const ScrDyn *value); +/* The values the iterator `method` gives for `source` (+1), or NULL with + * the exception pending. */ +ScrDyn *scr_dyn_iterate_with(const ScrDyn *source, ScrDyn *method); /* Keyed read on a FUNC node: the own-property table first (defineProperties * writes land there), then "name" (the box's best-effort static name; "" * for anonymous) and "length" (the boxed arity). Returns +1, or NULL when @@ -1600,6 +1619,12 @@ typedef struct ScrDynHandleOps { /* Past the depth limit util.inspect prints `[cls]` (the class's * inspector returns `this`) instead of the bare class name. */ bool inspect_bracketed_past_depth; + /* The class's inspector formats its view with a new util.inspect call + * (URL's does): the view renders from the top level with the caller's + * depth, and its lines take the caller's indentation. Past the depth + * limit the inspector returns the instance, which has no own + * properties, so util.inspect prints `cls {}`. */ + bool inspect_view_nested; /* The @@toStringTag when it differs from cls: String() answers * "[object ]" and util.inspect prints ` [] `, or * ` ` when the tag ends with "." and cls, as Node does. */ diff --git a/packages/runtime/src/scr_dyn_invoke.c b/packages/runtime/src/scr_dyn_invoke.c index c8093f64c..1dd5711a0 100644 --- a/packages/runtime/src/scr_dyn_invoke.c +++ b/packages/runtime/src/scr_dyn_invoke.c @@ -191,13 +191,6 @@ static double dyn_index_arg(ScrDyn *const *args, size_t argc, size_t i, double d return isnan(number) ? 0 : trunc(number); } -static double dyn_bytes_index_arg(ScrDyn *const *args, size_t argc, size_t index, double fallback) { - if (index >= argc || args[index]->kind == SCR_DYN_UNDEF) return fallback; - double value; - if (!scr_dyn_number_coerce_js(args[index], &value)) return 0; - return isnan(value) ? 0 : trunc(value); -} - /* JS relative-index normalization (slice's rule). */ static size_t dyn_rel_index(double rel, size_t len) { if (rel < 0) { @@ -716,7 +709,8 @@ static bool dyn_bytes_proto_real(int m) { case DYN_M_every: case DYN_M_find: case DYN_M_findIndex: case DYN_M_reverse: case DYN_M_fill: case DYN_M_set: case DYN_M_subarray: case DYN_M_sort: case DYN_M_keys: case DYN_M_values: case DYN_M_entries: case DYN_M_reduce: case DYN_M_reduceRight: case DYN_M_copyWithin: - case DYN_M_toString: case DYN_M_toLocaleString: + case DYN_M_toString: case DYN_M_toLocaleString: case DYN_M_findLast: case DYN_M_findLastIndex: + case DYN_M_toReversed: case DYN_M_toSorted: case DYN_M_with: return true; default: return false; @@ -1660,63 +1654,9 @@ static ScrDyn *scr_dyn_invoke_impl( dyn_throw_not_fn(what); return NULL; } - size_t blen = bytes->len; - if ((mid == DYN_M_at)) { - double iD = dyn_bytes_index_arg(args, argc, 0, 0); - if (scr_exc_pending()) return NULL; - double idx = iD < 0 ? (double)blen + iD : iD; - if (idx < 0 || idx >= (double)blen) return scr_dyn_retain(scr_dyn_undefined()); - return scr_dyn_new_num(scr_bytes_get(bytes, idx)); - } - if ((mid == DYN_M_slice) || (mid == DYN_M_subarray)) { - /* subarray and Buffer.slice alias their source. TypedArray.slice - * owns an independent copy; all keep the receiver's Buffer flavor. */ - double startD = dyn_bytes_index_arg(args, argc, 0, 0); - if (scr_exc_pending()) return NULL; - double endD = dyn_bytes_index_arg(args, argc, 1, (double)blen); - if (scr_exc_pending()) return NULL; - ScrBytes *out = recv->buffer || (mid == DYN_M_subarray) - ? scr_bytes_subarray(bytes, startD, endD) : scr_bytes_slice(bytes, startD, endD); - ScrDyn *d = recv->buffer ? scr_dyn_new_buffer(out) : scr_dyn_new_bytes(out); - scr_bytes_release(out); - return d; - } - if ((mid == DYN_M_set)) { - double offset = dyn_bytes_index_arg(args, argc, 1, 0); - if (scr_exc_pending()) return NULL; - scr_bytes_set_from_dyn(bytes, argc ? args[0] : scr_dyn_undefined(), offset); - return scr_exc_pending() ? NULL : scr_dyn_retain(scr_dyn_undefined()); - } - if ((mid == DYN_M_copyWithin)) { - double target = dyn_bytes_index_arg(args, argc, 0, 0); - if (scr_exc_pending()) return NULL; - double start = dyn_bytes_index_arg(args, argc, 1, 0); - if (scr_exc_pending()) return NULL; - double end = dyn_bytes_index_arg(args, argc, 2, (double)blen); - if (scr_exc_pending()) return NULL; - scr_bytes_release(scr_bytes_copy_within(bytes, target, start, end)); - return scr_dyn_retain(recv); - } - if ((mid == DYN_M_fill) && !recv->buffer) { - double value; - if (!scr_dyn_number_coerce_js(argc ? args[0] : scr_dyn_undefined(), &value)) return NULL; - double start = dyn_bytes_index_arg(args, argc, 1, 0); - if (scr_exc_pending()) return NULL; - double end = dyn_bytes_index_arg(args, argc, 2, (double)blen); - if (scr_exc_pending()) return NULL; - scr_bytes_release(scr_bytes_fill_elem(bytes, value, start, end)); - return scr_dyn_retain(recv); - } - if ((mid == DYN_M_join) || ((mid == DYN_M_toString) && !recv->buffer)) { - ScrStr *separator = (mid == DYN_M_join) && argc && args[0]->kind != SCR_DYN_UNDEF - ? scr_dyn_string_coerce_js(args[0]) : scr_str_new(",", 1); - if (scr_exc_pending()) { scr_str_release(separator); return NULL; } - ScrStr *joined = scr_bytes_join(bytes, separator); - scr_str_release(separator); - ScrDyn *out = scr_dyn_new_str(joined); - scr_str_release(joined); - return out; - } + bool handled; + ScrDyn *answer = scr_dyn_bytes_method(recv, method, args, argc, &handled); + if (handled) return answer; if (dyn_bytes_proto_real(mid)) { dyn_throw_unsupported(scr_bytes_elem_name(bytes->elem), method); return NULL; @@ -1984,6 +1924,9 @@ static ScrDyn *dyn_global_ctor(const char *name) { dyn_global_ctors[i] = scr_dyn_new_func(scr_closure_new((void *)dyn_global_ctor_names[i], 0), dyn_global_ctor_call, length, dyn_s6, dyn_global_ctor_names[i]); + /* `o.constructor.prototype` of a plain object is Object.prototype + * (zod's isPlainObject). The other prototypes are not modeled. */ + if (i == 0) scr_dyn_fn_seed_prototype(dyn_global_ctors[i], scr_dyn_object_prototype()); } return scr_dyn_retain(dyn_global_ctors[i]); } diff --git a/packages/runtime/src/scr_error.h b/packages/runtime/src/scr_error.h index fbb64aad9..4962db217 100644 --- a/packages/runtime/src/scr_error.h +++ b/packages/runtime/src/scr_error.h @@ -48,6 +48,12 @@ typedef struct ScrClassObj { size_t length; struct ScrBox *prototype_data; struct ScrBox *static_data; + /* The base class's name, which util.inspect prints as + * `[class C extends B]`; NULL without a named base. */ + const ScrStr *base_name; + /* Nonzero when the class declares public static fields, which the + * class object does not carry without static_data. */ + size_t own_static_fields; struct ScrBox *caps[]; } ScrClassObj; diff --git a/packages/runtime/src/scr_events.c b/packages/runtime/src/scr_events.c index 3391f54b1..6e0bf5146 100644 --- a/packages/runtime/src/scr_events.c +++ b/packages/runtime/src/scr_events.c @@ -388,8 +388,80 @@ static SCR_TL bool scr_stdin_destroyed = false; static SCR_TL bool scr_stdin_paused = false; static SCR_TL bool scr_stdin_resumed = false; static SCR_TL bool scr_stdin_read_eof = false; -static SCR_TL ScrBytes *scr_stdin_buffer; +/* Input held for read() and later consumers, as Node's BufferList: the + * chunks in arrival order and their total length, so an arrival appends + * without copying what is already held. */ +static SCR_TL ScrBytes **scr_stdin_held = NULL; +static SCR_TL size_t scr_stdin_nheld = 0, scr_stdin_held_cap = 0; +static SCR_TL size_t scr_stdin_buffered = 0; static SCR_TL size_t scr_stdin_read_demand; +/* 'readable' listeners (paused mode, as Node's once one is added): input + * stays buffered for read(), and the event fires on the next tick when + * input arrives while a read wanted more (`need`), and once at EOF. */ +static SCR_TL ScrStdinEndL *scr_stdin_readable = NULL; +static SCR_TL size_t scr_stdin_nreadable = 0, scr_stdin_readable_cap = 0; +static SCR_TL bool scr_stdin_readable_need = false; +static SCR_TL bool scr_stdin_readable_queued = false; + +/* Appends an arrived chunk (moves) to the held input. */ +static void scr_stdin_hold(ScrBytes *chunk) { + if (chunk->len == 0) { + scr_bytes_release(chunk); + return; + } + if (scr_stdin_nheld == scr_stdin_held_cap) { + scr_stdin_held_cap = scr_stdin_held_cap ? scr_stdin_held_cap * 2 : 4; + scr_stdin_held = realloc(scr_stdin_held, scr_stdin_held_cap * sizeof *scr_stdin_held); + if (!scr_stdin_held) scr_events_oom(); + } + scr_stdin_held[scr_stdin_nheld++] = chunk; + scr_stdin_buffered += chunk->len; +} + +/* The first n held bytes as one chunk (+1), 0 < n <= scr_stdin_buffered. + * A whole first chunk moves out without a copy; otherwise the bytes are + * joined once, and a partly taken chunk keeps its rest. */ +static ScrBytes *scr_stdin_take(size_t n) { + ScrBytes *first = scr_stdin_held[0]; + size_t used = 0; + ScrBytes *out; + if (n == first->len) { + out = first; + used = 1; + } else if (n < first->len) { + out = scr_bytes_slice(first, 0, (double)n); + scr_stdin_held[0] = scr_bytes_slice(first, (double)n, (double)first->len); + scr_bytes_release(first); + } else { + out = scr_bytes_new(SCR_BYTES_U8, (double)n); + size_t at = 0; + while (at < n) { + ScrBytes *chunk = scr_stdin_held[used]; + size_t part = chunk->len <= n - at ? chunk->len : n - at; + memcpy(out->data + at, chunk->data, part); + at += part; + if (part == chunk->len) { + scr_bytes_release(chunk); + used++; + } else { + scr_stdin_held[used] = scr_bytes_slice(chunk, (double)part, (double)chunk->len); + scr_bytes_release(chunk); + } + } + } + memmove(scr_stdin_held, scr_stdin_held + used, (scr_stdin_nheld - used) * sizeof *scr_stdin_held); + scr_stdin_nheld -= used; + scr_stdin_buffered -= n; + return out; +} + +static void scr_stdin_drop_held(void) { + for (size_t i = 0; i < scr_stdin_nheld; i++) scr_bytes_release(scr_stdin_held[i]); + free(scr_stdin_held); + scr_stdin_held = NULL; + scr_stdin_nheld = scr_stdin_held_cap = 0; + scr_stdin_buffered = 0; +} #ifdef SCR_STDIO_EXTENDED /* process.stdin.setEncoding(enc): the canonical encoding name (NULL until @@ -475,6 +547,78 @@ void scr_stdin_on_end(ScrClosure *cb /*moves*/, bool once) { scr_stdin_nend++; } +static void scr_stdin_finish(bool fire_end); + +static void scr_stdin_emit_readable(void) { + scr_stdin_readable_queued = false; + size_t length = scr_stdin_buffered; + if (scr_stdin_eof || scr_stdin_destroyed || (!length && !scr_stdin_read_eof)) return; + size_t n = scr_stdin_nreadable; + ScrStdinEndL *snap = malloc((n ? n : 1) * sizeof *snap); + if (!snap) scr_events_oom(); + for (size_t i = 0; i < n; i++) { + snap[i] = scr_stdin_readable[i]; + scr_closure_retain(snap[i].cb); + } + for (size_t i = 0; i < n; i++) { + if (snap[i].once) { + for (size_t j = 0; j < scr_stdin_nreadable; j++) { + if (scr_stdin_readable[j].cb == snap[i].cb) { + scr_closure_release(scr_stdin_readable[j].cb); + memmove(scr_stdin_readable + j, scr_stdin_readable + j + 1, + (scr_stdin_nreadable - j - 1) * sizeof *scr_stdin_readable); + scr_stdin_nreadable--; + break; + } + } + } + if (!scr_exc_pending() && !scr_stdin_eof && !scr_stdin_destroyed) + ((void (*)(ScrClosure *))snap[i].cb->fn)(snap[i].cb); + scr_closure_release(snap[i].cb); + } + free(snap); + length = scr_stdin_buffered; + /* Another event is due once the buffer reaches the 64 KiB mark, or the + * larger size a listener's read(size) asked for. */ + scr_stdin_readable_need = + !scr_stdin_read_eof && (length <= 65536 || length < scr_stdin_read_demand); +} + +static void scr_stdin_queue_readable(void) { + if (scr_stdin_readable_queued || !scr_stdin_nreadable) return; + scr_stdin_readable_queued = true; + scr_next_tick_raw(scr_stdin_emit_readable); +} + +/* Adding a 'readable' listener starts reading ahead to the 64 KiB mark; a + * buffer that already holds input fires the event at once (next tick). */ +static void scr_stdin_on_readable(ScrClosure *cb /*moves*/, bool once) { + if (scr_stdin_eof || scr_stdin_destroyed) { + scr_closure_release(cb); + return; + } + if (scr_stdin_nreadable == scr_stdin_readable_cap) { + scr_stdin_readable_cap = scr_stdin_readable_cap ? scr_stdin_readable_cap * 2 : 2; + scr_stdin_readable = realloc(scr_stdin_readable, scr_stdin_readable_cap * sizeof *scr_stdin_readable); + if (!scr_stdin_readable) scr_events_oom(); + } + scr_stdin_readable[scr_stdin_nreadable].cb = cb; + scr_stdin_readable[scr_stdin_nreadable].once = once; + scr_stdin_nreadable++; + scr_stdin_readable_need = true; + if (scr_stdin_read_demand < 65536) scr_stdin_read_demand = 65536; + if (scr_stdin_buffered) scr_stdin_queue_readable(); +} + +/* The input ended: with 'readable' listeners the event fires once more and + * 'end' waits for the read that finds nothing left; otherwise 'end' fires + * once the buffer is drained. */ +static void scr_stdin_reached_eof(void) { + scr_stdin_read_eof = true; + if (scr_stdin_nreadable) scr_stdin_queue_readable(); + else if (!scr_stdin_buffered) scr_stdin_finish(true); +} + void scr_stdin_on_error(ScrClosure *cb /*moves*/, ScrChildErrFn fn, bool once) { if (scr_stdin_eof || scr_stdin_destroyed) { scr_closure_release(cb); @@ -516,10 +660,15 @@ bool scr_stdin_ended(void) { return scr_stdin_eof || scr_stdin_destroyed; } * alive (a paused Node stdin with only those never flows — the process * exits with them registered). */ static bool scr_stdin_watching(void) { - return !scr_stdin_eof && !scr_stdin_destroyed && - ((!scr_stdin_paused && (scr_stdin_ndata > 0 || scr_stdin_resumed)) || - scr_stdin_waiter != NULL || - (!scr_stdin_read_eof && scr_stdin_read_demand > (scr_stdin_buffer ? scr_stdin_buffer->len : 0))); + if (scr_stdin_eof || scr_stdin_destroyed) return false; + /* 'readable' listeners keep the stream paused, as in Node, where + * resume() and 'data' listeners do not make it flow: it reads ahead only + * while a read wants more than is held (the 64 KiB mark, or a larger + * read(size)), and stops until something drains it. */ + if (scr_stdin_nreadable) return !scr_stdin_read_eof && scr_stdin_read_demand > scr_stdin_buffered; + return (!scr_stdin_paused && (scr_stdin_ndata > 0 || scr_stdin_resumed)) || + scr_stdin_waiter != NULL || + (!scr_stdin_read_eof && scr_stdin_read_demand > scr_stdin_buffered); } bool scr_stdin_pending(void) { return scr_stdin_watching(); } @@ -528,6 +677,10 @@ static void scr_stdin_drop_listeners(void) { for (size_t i = 0; i < scr_stdin_ndata; i++) scr_closure_release(scr_stdin_data[i].cb); for (size_t i = 0; i < scr_stdin_nend; i++) scr_closure_release(scr_stdin_end[i].cb); for (size_t i = 0; i < scr_stdin_nerr; i++) scr_closure_release(scr_stdin_err[i].cb); + for (size_t i = 0; i < scr_stdin_nreadable; i++) scr_closure_release(scr_stdin_readable[i].cb); + free(scr_stdin_readable); + scr_stdin_readable = NULL; + scr_stdin_nreadable = scr_stdin_readable_cap = 0; free(scr_stdin_data); free(scr_stdin_end); free(scr_stdin_err); @@ -593,8 +746,7 @@ static void scr_stdin_finish(bool fire_end) { void scr_stdin_destroy(void) { if (scr_stdin_destroyed) return; scr_stdin_destroyed = true; - scr_bytes_release(scr_stdin_buffer); - scr_stdin_buffer = NULL; + scr_stdin_drop_held(); scr_stdin_read_demand = 0; scr_stdin_settle_done(); scr_stdin_drop_listeners(); @@ -627,16 +779,9 @@ static void scr_stdin_deliver(ScrBytes *chunk); /* A chunk that arrived (moves): delivered, or buffered while paused or * without a consumer. */ static void scr_stdin_arrived(ScrBytes *chunk) { - if (scr_stdin_paused || (!scr_stdin_ndata && !scr_stdin_resumed && !scr_stdin_waiter)) { - if (scr_stdin_buffer) { - size_t before = scr_stdin_buffer->len; - ScrBytes *joined = scr_bytes_new(SCR_BYTES_U8, (double)(before + chunk->len)); - memcpy(joined->data, scr_stdin_buffer->data, before); - memcpy(joined->data + before, chunk->data, chunk->len); - scr_bytes_release(scr_stdin_buffer); - scr_bytes_release(chunk); - scr_stdin_buffer = joined; - } else scr_stdin_buffer = chunk; + if (scr_stdin_paused || scr_stdin_nreadable || (!scr_stdin_ndata && !scr_stdin_resumed && !scr_stdin_waiter)) { + if (scr_stdin_nreadable && scr_stdin_readable_need) scr_stdin_queue_readable(); + scr_stdin_hold(chunk); return; } scr_stdin_deliver(chunk); @@ -645,15 +790,18 @@ static void scr_stdin_arrived(ScrBytes *chunk) { static void scr_stdin_service(void) { if (!scr_stdin_watching()) return; - if (!scr_stdin_paused && scr_stdin_buffer) { - ScrBytes *chunk = scr_stdin_buffer; - scr_stdin_buffer = NULL; + /* Buffered input goes to a consumer: 'data' listeners, a resumed + * stream, or a parked for-await read. After the last 'readable' listener + * it stays buffered until one arrives, as in Node. */ + if (!scr_stdin_paused && !scr_stdin_nreadable && scr_stdin_buffered && + (scr_stdin_ndata > 0 || scr_stdin_resumed || scr_stdin_waiter != NULL)) { + ScrBytes *chunk = scr_stdin_take(scr_stdin_buffered); scr_stdin_deliver(chunk); scr_bytes_release(chunk); return; } if (scr_stdin_read_eof) { - if (!scr_stdin_buffer) scr_stdin_finish(true); + if (!scr_stdin_buffered && !scr_stdin_nreadable) scr_stdin_finish(true); return; } if (scr_stdin_fed) { @@ -662,10 +810,7 @@ static void scr_stdin_service(void) { bool ended = false; ScrBytes *chunk = scr_stdin_fed_take(&ended); if (chunk) scr_stdin_arrived(chunk); - else if (ended) { - scr_stdin_read_eof = true; - if (!scr_stdin_buffer) scr_stdin_finish(true); - } + else if (ended) scr_stdin_reached_eof(); return; } #ifdef _WIN32 @@ -727,8 +872,7 @@ static void scr_stdin_service(void) { return; } if (n == 0) { - scr_stdin_read_eof = true; - if (!scr_stdin_buffer) scr_stdin_finish(true); + scr_stdin_reached_eof(); return; } ScrBytes *chunk = scr_bytes_new(SCR_BYTES_U8, (double)n); @@ -802,6 +946,8 @@ static void scr_stdin_deliver(ScrBytes *chunk) { #endif ScrPromise *p = scr_stdin_waiter; scr_stdin_waiter = NULL; + /* Node's stdin yields Buffers. */ + chunk->is_buffer = true; scr_promise_fulfill_ref(p, scr_bytes_retain(chunk), scr_bytes_retain_v, scr_bytes_release_v, NULL); scr_promise_release(p); @@ -878,6 +1024,7 @@ static void scr_stdio_data_text(ScrClosure *cb, ScrStr *text) { } #endif static void scr_stdio_end(ScrClosure *cb) { scr_stdio_fire(cb, NULL, 0); } +static void scr_stdio_readable(ScrClosure *cb) { scr_stdio_fire(cb, NULL, 0); } static void scr_stdio_error(ScrClosure *cb, ScrStr *message) { ScrError *error = scr_error_new(SCR_ERR_ERROR, message); ScrDyn *arg = scr_dyn_from_error(error); @@ -971,7 +1118,7 @@ static void scr_stdio_queue_write_error(ScrStdio *stream, ScrDyn *callback, int } static void scr_stdio_finish_read(void) { - if (scr_stdin_read_eof && !scr_stdin_buffer && !scr_stdin_eof && !scr_stdin_destroyed) + if (scr_stdin_read_eof && !scr_stdin_buffered && !scr_stdin_eof && !scr_stdin_destroyed) scr_stdin_finish(true); } @@ -980,21 +1127,21 @@ static ScrDyn *scr_stdio_read(ScrDyn *size) { if (!all && (size->kind != SCR_DYN_NUM || !isfinite(size->v.num) || size->v.num < 0 || size->v.num > 1073741824 || floor(size->v.num) != size->v.num)) return scr_stdio_refusal("read size"); - size_t available = scr_stdin_buffer ? scr_stdin_buffer->len : 0; + size_t available = scr_stdin_buffered; size_t wanted = all ? available : (size_t)size->v.num; if (scr_stdin_read_eof && wanted > available) wanted = available; if (wanted == 0 || wanted > available) { if (!scr_stdin_eof && !scr_stdin_destroyed) { + scr_stdin_readable_need = true; scr_stdin_read_demand = wanted > 65536 ? wanted : 65536; if (scr_stdin_read_eof) scr_next_tick_raw(scr_stdio_finish_read); } return scr_dyn_new_null(); } - ScrBytes *chunk = scr_bytes_slice(scr_stdin_buffer, 0, (double)wanted); - ScrBytes *rest = wanted < available ? scr_bytes_slice(scr_stdin_buffer, (double)wanted, (double)available) : NULL; - scr_bytes_release(scr_stdin_buffer); - scr_stdin_buffer = rest; + ScrBytes *chunk = scr_stdin_take(wanted); + bool rest = scr_stdin_buffered > 0; scr_stdin_read_demand = 65536; + if (!rest && !scr_stdin_read_eof) scr_stdin_readable_need = true; scr_stdin_deliver(chunk); ScrDyn *result = scr_dyn_new_chunk(chunk); scr_bytes_release(chunk); @@ -1150,12 +1297,14 @@ static ScrDyn *scr_stdio_method(ScrClosure *cb, ScrDyn *const *args, size_t argc bool data = arg->kind == SCR_DYN_STR && arg->v.str->len == 4 && memcmp(event, "data", 4) == 0; bool end = arg->kind == SCR_DYN_STR && arg->v.str->len == 3 && memcmp(event, "end", 3) == 0; bool error = arg->kind == SCR_DYN_STR && arg->v.str->len == 5 && memcmp(event, "error", 5) == 0; + bool readable = stream->fd == 0 && arg->kind == SCR_DYN_STR && arg->v.str->len == 8 && + memcmp(event, "readable", 8) == 0; #ifdef SCR_STDIO_EXTENDED bool resize = stream->fd != 0 && arg->kind == SCR_DYN_STR && arg->v.str->len == 6 && memcmp(event, "resize", 6) == 0; - if ((!data && !end && !error && !resize) || (stream->fd != 0 && !error && !resize)) { + if ((!data && !end && !error && !readable && !resize) || (stream->fd != 0 && !error && !resize)) { #else - if ((!data && !end && !error) || (stream->fd != 0 && !error)) { + if ((!data && !end && !error && !readable) || (stream->fd != 0 && !error)) { #endif result = scr_stdio_refusal("event"); goto done; @@ -1175,6 +1324,7 @@ static ScrDyn *scr_stdio_method(ScrClosure *cb, ScrDyn *const *args, size_t argc if (data) scr_stdin_on_data(scr_stdio_callback(listener, (void *)scr_stdio_data), scr_stdio_data, once); #endif if (end) scr_stdin_on_end(scr_stdio_callback(listener, (void *)scr_stdio_end), once); + if (readable) scr_stdin_on_readable(scr_stdio_callback(listener, (void *)scr_stdio_readable), once); if (error) scr_stdin_on_error(scr_stdio_callback(listener, (void *)scr_stdio_error), scr_stdio_error, once); } else { #define REMOVE_STDIO_LISTENER(list, count, fire) \ @@ -1187,6 +1337,7 @@ static ScrDyn *scr_stdio_method(ScrClosure *cb, ScrDyn *const *args, size_t argc } if (data) { REMOVE_STDIO_LISTENER(scr_stdin_data, scr_stdin_ndata, scr_stdio_data); } if (end) { REMOVE_STDIO_LISTENER(scr_stdin_end, scr_stdin_nend, scr_stdio_end); } + if (readable) { REMOVE_STDIO_LISTENER(scr_stdin_readable, scr_stdin_nreadable, scr_stdio_readable); } if (error) { REMOVE_STDIO_LISTENER(scr_stdin_err, scr_stdin_nerr, scr_stdio_error); } #undef REMOVE_STDIO_LISTENER } @@ -1246,7 +1397,7 @@ static ScrDyn *scr_stdio_get(void *ptr, const char *key, size_t length) { return dimension < 0 ? scr_dyn_retain(scr_dyn_undefined()) : scr_dyn_new_num(dimension); } if (stream->fd == 0 && length == 14 && memcmp(key, "readableLength", 14) == 0) - return scr_dyn_new_num(scr_stdin_buffer ? (double)scr_stdin_buffer->len : 0); + return scr_dyn_new_num((double)scr_stdin_buffered); if (stream->fd == 0 && length == 5 && memcmp(key, "isRaw", 5) == 0) return scr_process_is_tty(0) ? scr_dyn_new_bool(scr_stdio_raw) : scr_dyn_retain(scr_dyn_undefined()); if (stream->fd == 0 && length == 9 && memcmp(key, "destroyed", 9) == 0) return scr_dyn_new_bool(scr_stdin_destroyed); @@ -1531,8 +1682,7 @@ static void scr_events_cleanup_atexit(void) { if (scr_context_is_main()) scr_sig_cleanup(); scr_stdin_settle_done(); scr_stdin_drop_listeners(); - scr_bytes_release(scr_stdin_buffer); - scr_stdin_buffer = NULL; + scr_stdin_drop_held(); if (scr_stdio_initialized) scr_stdio_cleanup(); } diff --git a/packages/runtime/src/scr_inspect.c b/packages/runtime/src/scr_inspect.c index 79b2564ff..333802c70 100644 --- a/packages/runtime/src/scr_inspect.c +++ b/packages/runtime/src/scr_inspect.c @@ -324,6 +324,9 @@ typedef struct { static SCR_TL InspSeenEnt *g_seen; static SCR_TL size_t g_nseen; +/* util.format's %o (scr_insp_dyn_hidden): this render shows hidden own + * properties, like util.inspect's showHidden. */ +static SCR_TL bool g_show_hidden; static SCR_TL size_t g_seen_cap; /* Detection-numbered circular targets (persist across the call). */ static SCR_TL const void *g_circ[64]; @@ -643,6 +646,54 @@ ScrStr *scr_insp_nested_end(ScrStr *prefix, ScrStr *inner) { return ib_take(&out); } +/* The inspector's state at the start of a top-level render. A render that + * an inspection refusal ends leaves its compiled frames open: the Error + * propagates out of the emitted helpers before their scr_insp_end and + * scr_insp_nested_end calls. The emitted render takes a mark first and + * unwinds to it on every exit (lower-inspect.ts), so later renders start + * from the state the refused one found. */ +typedef struct { + size_t nframes; + size_t nsaved; + size_t nseen; + size_t indent; + double cur_depth; +} InspMark; + +static SCR_TL InspMark *g_marks; +static SCR_TL size_t g_nmarks; +static SCR_TL size_t g_marks_cap; + +void scr_insp_mark(void) { + if (g_nmarks == g_marks_cap) { + g_marks_cap = g_marks_cap ? g_marks_cap * 2 : 4; + g_marks = realloc(g_marks, g_marks_cap * sizeof(InspMark)); + if (!g_marks) insp_oom(); + } + g_marks[g_nmarks++] = (InspMark){g_nframes, g_nsaved, g_nseen, g_indent, g_cur_depth}; +} + +void scr_insp_unwind(void) { + InspMark m = g_marks[--g_nmarks]; + while (g_nframes > m.nframes) { + InspFrame *f = &g_frames[--g_nframes]; + for (size_t i = 0; i < f->len; i++) scr_str_release(f->items[i]); + free(f->items); + } + while (g_nsaved > m.nsaved) { + InspSaved *sv = &g_saved[--g_nsaved]; + free(g_seen); + g_seen = sv->seen; + g_seen_cap = sv->seen_cap; + memcpy(g_circ, sv->circ, sizeof g_circ); + g_ncirc = sv->ncirc; + } + if (g_nseen > m.nseen) g_nseen = m.nseen; + g_indent = m.indent; + g_cur_depth = m.cur_depth; + g_pending_seen = NULL; +} + /* ── string values (formatPrimitive's string half) ───────────────────── */ /* Byte offset of UTF-16 unit `units` — when the boundary splits an astral @@ -1384,18 +1435,25 @@ static ScrStr *scr_insp_dyn_collection(ScrDyn *d, double recurse, double depth, return out; } -/* An own enumerable symbol-keyed property of `d` (borrowed), or NULL. */ +/* An own symbol-keyed property of `d` (borrowed) this render shows, or + * NULL: enumerable ones, and under showHidden the non-enumerable ones too. */ static ScrDynEntry *scr_insp_symbol_entry(ScrDyn *d, size_t i) { ScrDynEntry *ent = scr_dyn_own_symbol_entry(d, d->symbol_keys->v.arr.items[i]); - return ent && ent->enumerable ? ent : NULL; + return ent && (ent->enumerable || g_show_hidden) ? ent : NULL; } /* An ordinary object: `Name { key: value }` with its constructor name * `cls` (NULL for a plain object). Node's default view lists the own * enumerable string keys, then the own enumerable symbol keys. */ +/* An own entry this render shows: enumerable ones, and under showHidden + * the non-enumerable ones too (never the encoding's `%` markers). */ +static bool insp_obj_shows(const ScrDynEntry *ent) { + return ent->enumerable || (g_show_hidden && !(ent->key_len && ent->key[0] == '%')); +} + static ScrStr *scr_insp_obj(ScrDyn *d, double recurse, double depth, const char *cls) { size_t shown = 0; - for (size_t i = 0; i < d->v.obj.len; i++) shown += d->v.obj.entries[i].enumerable; + for (size_t i = 0; i < d->v.obj.len; i++) shown += insp_obj_shows(&d->v.obj.entries[i]); size_t nsymbols = d->symbol_keys ? d->symbol_keys->v.arr.len : 0; for (size_t i = 0; i < nsymbols; i++) shown += scr_insp_symbol_entry(d, i) != NULL; if (shown == 0) { @@ -1411,10 +1469,17 @@ static ScrStr *scr_insp_obj(ScrDyn *d, double recurse, double depth, const char scr_insp_begin(recurse + 1); for (size_t i = 0; i < d->v.obj.len; i++) { ScrDynEntry *ent = &d->v.obj.entries[i]; - if (!ent->enumerable) continue; - ScrStr *val = scr_insp_dyn(ent->value, recurse + 1, depth); + if (!insp_obj_shows(ent)) continue; + ScrStr *val = ent->accessor ? insp_accessor_tag(ent) : scr_insp_dyn(ent->value, recurse + 1, depth); InspBuf eb = {0}; - insp_key_into(&eb, ent->key, ent->key_len); + if (ent->enumerable) { + insp_key_into(&eb, ent->key, ent->key_len); + } else { + /* formatProperty's hidden key: the key's rendering in brackets. */ + ib_char(&eb, '['); + insp_key_into(&eb, ent->key, ent->key_len); + ib_char(&eb, ']'); + } ib_cstr(&eb, ": "); ib_bytes(&eb, val->data, val->len); scr_str_release(val); @@ -1426,9 +1491,12 @@ static ScrStr *scr_insp_obj(ScrDyn *d, double recurse, double depth, const char ScrDynEntry *ent = scr_insp_symbol_entry(d, i); if (!ent) continue; ScrStr *key = scr_insp_dyn(d->symbol_keys->v.arr.items[i], recurse + 1, depth); - ScrStr *val = scr_insp_dyn(ent->value, recurse + 1, depth); + ScrStr *val = ent->accessor ? insp_accessor_tag(ent) : scr_insp_dyn(ent->value, recurse + 1, depth); InspBuf eb = {0}; + /* A hidden symbol key is bracketed like a hidden string key. */ + if (!ent->enumerable) ib_char(&eb, '['); ib_bytes(&eb, key->data, key->len); + if (!ent->enumerable) ib_char(&eb, ']'); ib_cstr(&eb, ": "); ib_bytes(&eb, val->data, val->len); scr_str_release(key); @@ -1489,8 +1557,171 @@ ScrStr *scr_insp_typed_array(ScrBytes *b, double recurse, double depth) { return out; } +/* Node's function rendering: [Function: name] / [Function (anonymous)], + * and [class C extends B] / [class (anonymous)] for a class. The boxed + * name is the compiler's best-effort static spelling (SEMANTICS.md — + * reference-site naming). Enumerable own properties (a class's static + * fields, properties assigned to a function) follow in braces; past the + * depth limit such a function is [Function]. Borrows d; +1. */ +static ScrStr *scr_insp_dyn_func(ScrDyn *d, double recurse, double depth) { + const char *name = d->v.fn.name; + const ScrClassObj *cls = d->v.fn.class_obj; + ScrClosure *owner = scr_closure_identity(d->v.fn.clo); + ScrBox *props = owner->props ? owner->props : cls ? cls->static_data : NULL; + ScrDyn *table = props ? (ScrDyn *)scr_box_get_ref(props) : NULL; /* +1 */ + InspBuf out = {0}; + if (cls) { + ib_cstr(&out, "[class "); + ib_cstr(&out, name && name[0] ? name : "(anonymous)"); + const ScrDyn *base = table ? table->prototype : NULL; + if (cls->base_name && cls->base_name->len) { + ib_cstr(&out, " extends "); + ib_bytes(&out, cls->base_name->data, cls->base_name->len); + } else if (base && base->kind == SCR_DYN_FUNC && base->v.fn.name && base->v.fn.name[0]) { + ib_cstr(&out, " extends "); + ib_cstr(&out, base->v.fn.name); + } + ib_char(&out, ']'); + } else if (name && name[0]) { + ib_cstr(&out, "[Function: "); + ib_cstr(&out, name); + ib_char(&out, ']'); + } else { + ib_cstr(&out, "[Function (anonymous)]"); + } + ScrStr *tag = ib_take(&out); + if (cls && !props && cls->own_static_fields) { + /* Node prints the static fields after the tag; the class object + * does not hold them (the reflection fence's stance). */ + scr_str_release(tag); + static const char message[] = "util.inspect of a class with static fields through unknown is not supported yet"; + scr_throw_error_msg(SCR_ERR_ERROR, message, sizeof message - 1); + return scr_str_new("", 0); + } + size_t shown = 0; + if (table && table->kind == SCR_DYN_OBJ) { + for (size_t i = 0; i < table->v.obj.len; i++) shown += table->v.obj.entries[i].enumerable; + size_t nsymbols = table->symbol_keys ? table->symbol_keys->v.arr.len : 0; + for (size_t i = 0; i < nsymbols; i++) shown += scr_insp_symbol_entry(table, i) != NULL; + } + if (shown == 0) { + scr_dyn_release(table); + return tag; + } + /* A function already on the traversal stack renders as [Circular *N], + * even past the depth limit. Its identity is the class object for a class + * (each dynamic box of a class may carry its own closure) and the closure + * every box of a function shares otherwise. */ + const void *identity = cls ? (const void *)cls : (const void *)owner; + double circular = scr_insp_circ_check(identity); + if (circular > 0) { + scr_dyn_release(table); + scr_str_release(tag); + return scr_insp_circular(circular); + } + if (recurse > depth) { + scr_dyn_release(table); + scr_str_release(tag); + return scr_str_new("[Function]", 10); + } + char *prefix = malloc(tag->len + 1); + if (!prefix) scr_trap("scriptc: out of memory\n"); + memcpy(prefix, tag->data, tag->len); + prefix[tag->len] = '\0'; + scr_str_release(tag); + size_t nseen = g_nseen; + g_pending_seen = identity; + ScrStr *rendered = scr_insp_obj(table, recurse, depth, prefix); + g_pending_seen = NULL; + if (g_nseen > nseen) g_nseen = nseen; + free(prefix); + scr_dyn_release(table); + return rendered; +} + +/* Under showHidden, the kinds whose hidden entries this inspector does not + * render (a function's length/name/prototype, an error's stack, a typed + * array's byte fields, a native handle's internals): the kind's name, NULL + * for the kinds it renders. */ +static const char *insp_hidden_refusal(const ScrDyn *d) { + switch (d->kind) { + case SCR_DYN_FUNC: return "function"; + case SCR_DYN_BYTES: return d->buffer ? "Buffer" : d->v.bytes->is_data_view ? "DataView" : "typed array"; + case SCR_DYN_OBJ: return scr_dyn_obj_get(d, "%error", 6) != NULL ? "Error" : NULL; + case SCR_DYN_HANDLE: + return d->v.handle.tag == SCR_DYNH_MAP || d->v.handle.tag == SCR_DYNH_SET || + d->v.handle.tag == SCR_DYNH_DATE + ? NULL + : scr_dyn_handle_cls(d); + default: return NULL; + } +} + +ScrStr *scr_insp_bytes(ScrBytes *b, double recurse, double depth) { + if (b->is_data_view) return scr_insp_data_view(b, recurse, depth); + if (b->is_buffer) return scr_insp_buffer(b); + return scr_insp_typed_array(b, recurse, depth); +} + +/* Node's URLSearchParams inspector: [Object] past the depth limit, and + * otherwise each pair as `name => value` with both strings inspected, on + * one line, or one pair per line when the pairs' text is longer than + * breakLength (the closing brace stays on the last pair's line). The lines + * take the caller's indentation, as a custom inspector's text does. */ +static ScrStr *scr_insp_search_params(ScrSearchParams *sp, double recurse, double depth) { + if (recurse > depth) return scr_str_new("[Object]", 8); + size_t n = (size_t)scr_sp_size(sp); + if (n == 0) return scr_str_new("URLSearchParams {}", 18); + ScrStr **items = malloc(n * sizeof *items); + if (!items) insp_oom(); + double length = -2; + for (size_t i = 0; i < n; i++) { + ScrStr *name = scr_sp_key_at(sp, (double)i); + ScrStr *value = scr_sp_val_at(sp, (double)i); + ScrStr *name_text = scr_insp_str(name); + ScrStr *value_text = scr_insp_str(value); + InspBuf item = {0}; + ib_str(&item, name_text); + ib_cstr(&item, " => "); + ib_str(&item, value_text); + items[i] = ib_take(&item); + length += (double)insp_utf16_len(items[i]->data, items[i]->len) + 2; + scr_str_release(name); + scr_str_release(value); + scr_str_release(name_text); + scr_str_release(value_text); + } + bool multiline = length > g_break_length; + InspBuf out = {0}; + ib_cstr(&out, multiline ? "URLSearchParams {\n " : "URLSearchParams { "); + for (size_t i = 0; i < n; i++) { + if (i) ib_cstr(&out, multiline ? ",\n " : ", "); + ib_str(&out, items[i]); + scr_str_release(items[i]); + } + free(items); + ib_cstr(&out, " }"); + ScrStr *text = ib_take(&out); + InspBuf indented = {0}; + for (size_t k = 0; k < text->len; k++) { + ib_char(&indented, text->data[k]); + if (text->data[k] == '\n') ib_spaces(&indented, g_indent); + } + scr_str_release(text); + return ib_take(&indented); +} + ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth) { if (d->kind == SCR_DYN_PROXY) return scr_insp_dyn(d->v.proxy.target, recurse, depth); + const char *refused = g_show_hidden ? insp_hidden_refusal(d) : NULL; + if (refused) { + InspBuf out = {0}; + ib_cstr(&out, "util.format %o of "); + ib_cstr(&out, refused); + ib_cstr(&out, " values is not supported yet"); + scr_throw_error(SCR_ERR_ERROR, ib_take(&out)); + return scr_str_new("", 0); + } switch (d->kind) { case SCR_DYN_NULL: return scr_str_new("null", 4); @@ -1509,11 +1740,12 @@ ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth) { case SCR_DYN_ARR: { size_t len = d->v.arr.len; /* Named and noncanonical numeric properties follow the elements as - * `key: value` entries (Node's array extras). */ + * `key: value` entries (Node's array extras); under showHidden the + * own `length` comes first, and non-enumerable properties show too. */ const ScrDyn *props = d->v.arr.properties; size_t nprops = 0; - for (size_t i = 0; props && i < props->v.obj.len; i++) nprops += props->v.obj.entries[i].enumerable; - if (len == 0 && nprops == 0) return scr_str_new("[]", 2); + for (size_t i = 0; props && i < props->v.obj.len; i++) nprops += insp_obj_shows(&props->v.obj.entries[i]); + if (len == 0 && nprops == 0 && !g_show_hidden) return scr_str_new("[]", 2); if (recurse > depth) return scr_str_new("[Array]", 7); scr_insp_begin(recurse + 1); /* Node's maxArrayLength (100) counts output entries; a run of holes @@ -1545,12 +1777,27 @@ ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth) { scr_insp_entry(m, d->v.arr.items[i]->kind == SCR_DYN_NUM); scr_str_release(m); } + if (g_show_hidden) { + /* The own non-enumerable `length`, after the items. Node's + * grouping reads value[k] for every output position k, this one + * included. */ + char line[48]; + int n = snprintf(line, sizeof line, "[length]: %zu", len); + ScrStr *s = scr_str_new(line, (size_t)n); + scr_insp_entry(s, entries < len && (!presence || presence[entries]) && + d->v.arr.items[entries]->kind == SCR_DYN_NUM); + scr_str_release(s); + entries++; + } for (size_t k = 0; props && k < props->v.obj.len; k++) { const ScrDynEntry *ent = &props->v.obj.entries[k]; - if (!ent->enumerable) continue; + if (!insp_obj_shows(ent)) continue; ScrStr *val = ent->accessor ? insp_accessor_tag(ent) : scr_insp_dyn(ent->value, recurse + 1, depth); InspBuf eb = {0}; + /* formatProperty's hidden key: the key's rendering in brackets. */ + if (!ent->enumerable) ib_char(&eb, '['); insp_key_into(&eb, ent->key, ent->key_len); + if (!ent->enumerable) ib_char(&eb, ']'); ib_cstr(&eb, ": "); ib_bytes(&eb, val->data, val->len); scr_str_release(val); @@ -1564,8 +1811,8 @@ ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth) { entries++; } /* Node's grouping leaves out the last entry when there are more - * entries than maxArrayLength (the `... more items` entry when the - * array has no properties). */ + * entries than maxArrayLength (100): the `... more items` entry, + * `[length]` under showHidden, or the last property. */ bool last_out = entries > 100; ScrStr *base = scr_str_new("", 0); ScrStr *b0 = scr_str_new("[", 1); @@ -1587,59 +1834,8 @@ ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth) { * the bare marker (where a plain object says [Object]). */ return scr_insp_obj(d, recurse, depth, scr_dyn_class_name(d)); } - case SCR_DYN_FUNC: { - /* Node's function rendering: [Function: name] / [Function - * (anonymous)]. The boxed name is the compiler's best-effort static - * spelling (SEMANTICS.md — reference-site naming). */ - const char *name = d->v.fn.name; - InspBuf out = {0}; - if (name && name[0]) { - ib_cstr(&out, "[Function: "); - ib_cstr(&out, name); - ib_char(&out, ']'); - } else { - ib_cstr(&out, "[Function (anonymous)]"); - } - /* A function's own enumerable properties follow its base, as for an - * object (`[Function: f] { x: 1 }`), and past the depth limit it is - * `[Function]` (formatRaw). Classes keep the base. */ - ScrDyn *table = d->v.fn.class_obj ? NULL : scr_dyn_function_properties_existing(d); - bool shown = false; - for (size_t i = 0; table && i < table->v.obj.len && !shown; i++) shown = table->v.obj.entries[i].enumerable; - for (size_t i = 0; table && !shown && table->symbol_keys && i < table->symbol_keys->v.arr.len; i++) - shown = scr_insp_symbol_entry(table, i) != NULL; - if (!shown) { - scr_dyn_release(table); - return ib_take(&out); - } - /* Every value of one function shares its table: the table is the - * function's identity for the circular checks. */ - double circular = scr_insp_circ_check(table); - if (circular != 0) { - scr_dyn_release(table); - free(out.data); - return scr_insp_circular(circular); - } - if (recurse > depth) { - scr_dyn_release(table); - free(out.data); - return scr_str_new("[Function]", 10); - } - ScrStr *base = ib_take(&out); - char *cls = malloc(base->len + 1); - if (!cls) scr_trap("scriptc: out of memory\n"); - memcpy(cls, base->data, base->len); - cls[base->len] = '\0'; - scr_str_release(base); - size_t nseen = g_nseen; - g_pending_seen = table; - ScrStr *rendered = scr_insp_obj(table, recurse, depth, cls); - g_pending_seen = NULL; - if (g_nseen > nseen) g_nseen = nseen; - free(cls); - scr_dyn_release(table); - return rendered; - } + case SCR_DYN_FUNC: + return scr_insp_dyn_func(d, recurse, depth); case SCR_DYN_HANDLE: { if (d->v.handle.tag == SCR_DYNH_ARRAY_BUFFER || d->v.handle.tag == SCR_DYNH_SHARED_ARRAY_BUFFER) { @@ -1651,6 +1847,8 @@ ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth) { return scr_insp_weak_collection(d->v.handle.tag == SCR_DYNH_WEAK_MAP ? "WeakMap" : "WeakSet", recurse, depth); if (d->v.handle.tag == SCR_DYNH_DATE) return scr_insp_date(scr_dyn_native_date_value(d)); + if (d->v.handle.tag == SCR_DYNH_SEARCH_PARAMS) + return scr_insp_search_params(d->v.handle.ptr, recurse, depth); if (d->v.handle.tag == SCR_DYNH_ITERATOR) { ScrStr *iterator = scr_insp_native_iterator(d, recurse, depth); if (iterator) return iterator; @@ -1661,6 +1859,14 @@ ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth) { * depth limit (`depth < 0`); the ones that return `this` there * print util.inspect's `[cls]`. */ if (recurse > depth && !ops->inspect_view_empty) { + /* A nested-view inspector returns the instance itself there, + * which has no own properties: `URL {}`. */ + if (ops->inspect_view_nested) { + InspBuf out = {0}; + ib_cstr(&out, ops->cls); + ib_cstr(&out, " {}"); + return ib_take(&out); + } if (!ops->inspect_bracketed_past_depth) return scr_str_new(ops->cls, strlen(ops->cls)); InspBuf out = {0}; ib_char(&out, '['); @@ -1669,6 +1875,16 @@ ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth) { return ib_take(&out); } ScrDyn *view = ops->inspect_view(d->v.handle.ptr); + if (ops->inspect_view_nested) { + scr_insp_nested_begin(); + ScrStr *inner = scr_insp_dyn(view, 0, depth); + scr_dyn_release(view); + ScrStr *prefix = scr_str_new(ops->cls, strlen(ops->cls)); + ScrStr *rendered = scr_insp_nested_end(prefix, inner); + scr_str_release(prefix); + scr_str_release(inner); + return rendered; + } ScrStr *body = scr_insp_dyn(view, recurse, depth); scr_dyn_release(view); InspBuf out = {0}; @@ -1810,6 +2026,16 @@ ScrStr *scr_insp_dyn_s(ScrDyn *d, double depth) { return scr_insp_dyn(d, 0, depth); } +/* util.format's %o over a dyn value: util.inspect with showHidden at the + * given depth. */ +ScrStr *scr_insp_dyn_hidden(ScrDyn *d, double depth) { + bool outer = g_show_hidden; + g_show_hidden = true; + ScrStr *out = scr_insp_dyn(d, 0, depth); + g_show_hidden = outer; + return out; +} + /* ── console.table cells ─────────────────────────────────────────────── */ size_t scr_insp_display_width(const char *data, size_t len) { return insp_width(data, len); } diff --git a/packages/runtime/src/scr_inspect.h b/packages/runtime/src/scr_inspect.h index 5ac3aa9dd..8af60f0c0 100644 --- a/packages/runtime/src/scr_inspect.h +++ b/packages/runtime/src/scr_inspect.h @@ -45,8 +45,13 @@ ScrStr *scr_insp_dyn(ScrDyn *d, double recurse, double depth); /* A numeric typed array that is not a Buffer: `Uint8Array(n) [ ... ]`, * `[Uint8Array]` past the depth limit. Borrows b; +1. */ ScrStr *scr_insp_typed_array(ScrBytes *b, double recurse, double depth); +/* A u8 byte view whose static type does not say which one it is (a union + * arm, an element or field): a DataView, a Buffer () or a + * Uint8Array, by the view's own flags. */ +ScrStr *scr_insp_bytes(ScrBytes *b, double recurse, double depth); /* format's %s / rest-args twin: dyn strings pass verbatim. */ ScrStr *scr_insp_dyn_s(ScrDyn *d, double depth); +ScrStr *scr_insp_dyn_hidden(ScrDyn *d, double depth); /* %o: showHidden */ void scr_insp_begin(double recurse); /* util.inspect's breakLength, compact (0 for false) and sorted for the * renders that follow; the call site restores the defaults (80, 3, false) @@ -75,6 +80,10 @@ ScrStr *scr_insp_end(ScrStr *base, ScrStr *b0, ScrStr *b1, double recurse, * caller's level (+1; borrows both). */ void scr_insp_nested_begin(void); ScrStr *scr_insp_nested_end(ScrStr *prefix, ScrStr *inner); +/* Mark the inspector's state before a top-level render, and return to the + * mark when the render ends, normally or by an inspection refusal. */ +void scr_insp_mark(void); +void scr_insp_unwind(void); /* The buf.read* / buf.write* numeric families on u8 bytes, Node-exact: * boundsError's ladder (non-integer offset → 'It must be an integer', a @@ -115,6 +124,9 @@ ScrBytes *scr_fs_read_file_bytes(ScrStr *path); /* +1 */ * with the exception pending. */ ScrDyn *scr_fs_read_file_sync_dyn(ScrStr *path, const ScrDyn *enc); ScrStr *scr_fs_read_file_encoded(ScrStr *path, ScrStr *encoding); +/* readFileSync's encoding check (ERR_INVALID_ARG_VALUE), on its own: the + * check Node runs before it converts a URL path. */ +void scr_fs_check_read_encoding(ScrStr *encoding); ScrStr *scr_fs_read_fd_encoded(double fd, ScrStr *encoding); ScrDyn *scr_fs_callback_value(ScrStr *member); ScrDyn *scr_fs_callback_call(ScrStr *member, const ScrDyn *args); diff --git a/packages/runtime/src/scr_json.c b/packages/runtime/src/scr_json.c index 9cafc14b0..74fd53159 100644 --- a/packages/runtime/src/scr_json.c +++ b/packages/runtime/src/scr_json.c @@ -1924,6 +1924,8 @@ ScrDyn *scr_dyn_error_constructor(const char *name) { scr_error_ctor_values[i] = scr_dyn_new_func(scr_closure_new((void *)scr_error_ctor_names[i], 0), scr_error_ctor_call, length, "native:constructor", scr_error_ctor_names[i]); + /* Error.prototype is modeled; the other error prototypes are not. */ + if (i == 0) scr_dyn_fn_seed_prototype(scr_error_ctor_values[i], scr_dyn_error_prototype()); } return scr_dyn_retain(scr_error_ctor_values[i]); } @@ -2189,8 +2191,11 @@ ScrDyn *scr_dyn_obj_create(ScrDyn *prototype) { return object; } +static bool scr_dyn_error_view_on_error_prototype(const ScrDyn *object); + ScrDyn *scr_dyn_get_prototype(ScrDyn *object) { if (object == scr_builtin_object_prototype) return scr_dyn_new_null(); + if (object->kind == SCR_DYN_OBJ && scr_dyn_error_view_on_error_prototype(object)) return scr_dyn_error_prototype(); if (scr_dyn_class_reflection_fence(object)) return NULL; if (object->kind == SCR_DYN_TYPED_REF && strncmp(object->v.typed_ref.type_key, "object:", 7)) { ScrDyn *view = scr_dyn_typed_ref_materialize(object); @@ -4253,6 +4258,212 @@ static ScrDyn *scr_bytes_ctor_call(ScrClosure *closure, ScrDyn *const *args, siz scr_trap("scriptc: invalid typed array constructor\n"); } static ScrDyn *scr_dyn_fn_properties(const ScrDyn *function); + +/* The element kind a typed array constructor value makes, or -1. */ +static int scr_bytes_ctor_elem(const ScrDyn *callee) { + for (size_t i = 0; i < SCR_BYTES_ELEM_COUNT; i++) + if (callee->kind == SCR_DYN_FUNC && scr_bytes_ctors[i] && callee->v.fn.clo == scr_bytes_ctors[i]->v.fn.clo) return (int)i; + return -1; +} + +ScrDyn *scr_dyn_iterator_method(const ScrDyn *value) { + if (!scr_iterator_symbol || value->kind != SCR_DYN_OBJ) return NULL; + ScrDyn *method = scr_dyn_symbol_key_get(value, scr_iterator_symbol, true); + if (method && (method->kind == SCR_DYN_UNDEF || method->kind == SCR_DYN_NULL)) { + scr_dyn_release(method); + return NULL; + } + return method; +} + +ScrDyn *scr_dyn_iterate_with(const ScrDyn *source, ScrDyn *method) { + if (!scr_dyn_is_callable(method)) { + static const char message[] = "Symbol.iterator is not a function"; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + return NULL; + } + scr_dyn_this_push_dyn(source); + ScrDyn *iterator = scr_dyn_call(method, NULL, 0, "[Symbol.iterator]"); + scr_dyn_this_pop(); + if (!iterator) return NULL; + if (!scr_iterator_object(iterator)) { + scr_dyn_release(iterator); + static const char message[] = "Result of the Symbol.iterator method is not an object"; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + return NULL; + } + /* A generator or native iterator drains through its own iteration. */ + if (scr_builtin_iterable(iterator)) { + ScrDyn *drained = scr_dyn_destructure_rest(iterator, NULL); + scr_dyn_release(iterator); + return drained; + } + ScrDyn *next = scr_dyn_iterator_result_get(iterator, "next", 4); + ScrDyn *values = next ? scr_dyn_new_arr() : NULL; + while (values) { + scr_dyn_this_push_dyn(iterator); + ScrDyn *result = scr_dyn_call(next, NULL, 0, "next"); + scr_dyn_this_pop(); + ScrDyn *checked = result ? scr_dyn_iterator_result(result) : NULL; + scr_dyn_release(result); + if (!checked) { scr_dyn_release(values); values = NULL; break; } + ScrDyn *done = scr_dyn_iterator_result_get(checked, "done", 4); + bool finished = done && scr_dyn_truthy(done); + scr_dyn_release(done); + ScrDyn *value = !scr_exc_pending() && !finished ? scr_dyn_iterator_result_get(checked, "value", 5) : NULL; + scr_dyn_release(checked); + if (scr_exc_pending()) { scr_dyn_release(value); scr_dyn_release(values); values = NULL; break; } + if (finished) break; + scr_dyn_arr_push(values, value); + } + scr_dyn_release(next); + scr_dyn_release(iterator); + return values; +} + +/* The values of `source` when it is iterable (+1): a builtin iterable's + * own iteration, or an object's Symbol.iterator method, read once. NULL + * for an array-like source, or with the exception pending. */ +static ScrDyn *scr_dyn_from_iterated(const ScrDyn *source, bool *iterable) { + *iterable = true; + if (scr_builtin_iterable(source)) return scr_dyn_destructure_rest(source, NULL); + ScrDyn *method = scr_dyn_iterator_method(source); + if (!method) { *iterable = false; return NULL; } + ScrDyn *values = scr_dyn_iterate_with(source, method); + scr_dyn_release(method); + return values; +} + +/* TypedArrayCreate(C, [n]) for TypedArray.from and TypedArray.of: a typed + * array constructor makes one directly; any other constructor is called + * and must answer a typed array of at least n elements. */ +static ScrDyn *scr_bytes_static_create(ScrDyn *constructor, size_t n) { + int elem = scr_bytes_ctor_elem(constructor); + if (elem >= 0) { + ScrBytes *out = scr_bytes_new((ScrBytesElem)elem, (double)n); + ScrDyn *result = scr_dyn_new_bytes(out); + scr_bytes_release(out); + return result; + } + if (!scr_dyn_is_callable(constructor)) { + static const char message[] = "this is not a constructor"; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + return NULL; + } + ScrDyn *args = scr_dyn_new_arr(); + scr_dyn_arr_push(args, scr_dyn_new_num((double)n)); + ScrStr *what = scr_str_new("TypedArray species", 18); + ScrDyn *result = scr_dyn_construct(constructor, args, what); + scr_str_release(what); + scr_dyn_release(args); + if (!result) return NULL; + const char *problem = result->kind != SCR_DYN_BYTES || result->v.bytes->is_data_view + ? "this is not a typed array." + : result->v.bytes->len < n ? "Derived TypedArray constructor created an array which was too small" : NULL; + if (problem) { + scr_dyn_release(result); + scr_throw_error_msg(SCR_ERR_TYPE, problem, strlen(problem)); + return NULL; + } + return result; +} + +/* target[k] = value, converting with ToNumber as a typed array [[Set]] does. */ +static bool scr_bytes_static_set(ScrDyn *target, size_t k, const ScrDyn *value) { + double v; + if (!scr_dyn_number_coerce_js(value, &v)) return false; + if (k < target->v.bytes->len) scr_bytes_set(target->v.bytes, (double)k, v); + return true; +} + +/* mapfn(value, k) with thisArg, or the value itself (+1). */ +static ScrDyn *scr_bytes_static_map(ScrDyn *mapfn, ScrDyn *this_arg, ScrDyn *value, size_t k) { + if (!mapfn) return scr_dyn_retain(value); + ScrDyn *index = scr_dyn_new_num((double)k); + ScrDyn *cbargs[2] = { value, index }; + scr_dyn_this_push_dyn(this_arg); + ScrDyn *mapped = scr_dyn_call(mapfn, cbargs, 2, "mapfn"); + scr_dyn_this_pop(); + scr_dyn_release(index); + return mapped; +} + +/* TypedArray.from(source, mapfn, thisArg): an iterable source is drained + * first, then the target is created; an array-like source is read element + * by element after the target exists. */ +static ScrDyn *scr_bytes_from_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) { + (void)closure; + ScrDyn *constructor = scr_dyn_this_get(); + ScrDyn *result = NULL, *values = NULL; + ScrDyn *source = argc ? args[0] : scr_dyn_undefined(); + ScrDyn *mapfn = argc > 1 && args[1]->kind != SCR_DYN_UNDEF ? args[1] : NULL; + ScrDyn *this_arg = argc > 2 ? args[2] : scr_dyn_undefined(); + if (scr_bytes_ctor_elem(constructor) < 0 && !scr_dyn_is_callable(constructor)) { + static const char message[] = "this is not a constructor"; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + goto done; + } + if (mapfn && !scr_dyn_is_callable(mapfn)) { + static const char message[] = "TypedArray.from: the mapping function is not callable"; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + goto done; + } + if (source->kind == SCR_DYN_UNDEF || source->kind == SCR_DYN_NULL) { + static const char message[] = "Cannot convert undefined or null to object"; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + goto done; + } + bool iterable; + values = scr_dyn_from_iterated(source, &iterable); + if (iterable) { + if (!values) goto done; + size_t n = values->v.arr.len; + result = scr_bytes_static_create(constructor, n); + for (size_t k = 0; result && k < n; k++) { + ScrDyn *mapped = scr_bytes_static_map(mapfn, this_arg, values->v.arr.items[k], k); + bool ok = mapped && scr_bytes_static_set(result, k, mapped); + scr_dyn_release(mapped); + if (!ok) { scr_dyn_release(result); result = NULL; } + } + goto done; + } + if (scr_exc_pending()) goto done; + double n = 0; + if (source->kind == SCR_DYN_OBJ) { + ScrDyn *length = scr_dyn_obj_read(source, "length", 6); + bool ok = !scr_exc_pending() && (!length || scr_dyn_number_coerce_js(length, &n)); + scr_dyn_release(length); + if (!ok) goto done; + n = isnan(n) || n < 0 ? 0 : n > 9007199254740991.0 ? 9007199254740991.0 : trunc(n); + } + result = scr_bytes_static_create(constructor, (size_t)n); + for (size_t k = 0; result && k < (size_t)n; k++) { + char key[32]; + int size = snprintf(key, sizeof key, "%zu", k); + ScrDyn *item = scr_dyn_obj_read(source, key, (size_t)size); + ScrDyn *mapped = scr_exc_pending() ? NULL : scr_bytes_static_map(mapfn, this_arg, item ? item : scr_dyn_undefined(), k); + bool ok = mapped && scr_bytes_static_set(result, k, mapped); + scr_dyn_release(item); + scr_dyn_release(mapped); + if (!ok) { scr_dyn_release(result); result = NULL; } + } +done: + scr_dyn_release(values); + scr_dyn_release(constructor); + return result; +} + +/* TypedArray.of(...items). */ +static ScrDyn *scr_bytes_of_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) { + (void)closure; + ScrDyn *constructor = scr_dyn_this_get(); + ScrDyn *result = scr_bytes_static_create(constructor, argc); + for (size_t k = 0; result && k < argc; k++) + if (!scr_bytes_static_set(result, k, args[k])) { scr_dyn_release(result); result = NULL; } + scr_dyn_release(constructor); + return result; +} + static ScrDyn *scr_bytes_constructor_for(ScrBytesElem elem) { if (!scr_bytes_ctors[elem]) { bool initialized = false; @@ -4264,6 +4475,14 @@ static ScrDyn *scr_bytes_constructor_for(ScrBytesElem elem) { scr_dyn_obj_set(properties, "BYTES_PER_ELEMENT", 17, scr_dyn_new_num((double)scr_bytes_elem_size(elem))); ScrDynEntry *entry = &properties->v.obj.entries[properties->v.obj.len - 1]; entry->writable = entry->enumerable = entry->configurable = false; + /* from and of live on %TypedArray%, which is not modeled: each + * constructor carries them as non-enumerable properties. */ + scr_dyn_obj_set(properties, "from", 4, + scr_dyn_new_func(scr_closure_new(NULL, 0), scr_bytes_from_call, 1, "native:TypedArray", "from")); + properties->v.obj.entries[properties->v.obj.len - 1].enumerable = false; + scr_dyn_obj_set(properties, "of", 2, + scr_dyn_new_func(scr_closure_new(NULL, 0), scr_bytes_of_call, 0, "native:TypedArray", "of")); + properties->v.obj.entries[properties->v.obj.len - 1].enumerable = false; scr_dyn_release(properties); } return scr_dyn_retain(scr_bytes_ctors[elem]); @@ -4306,6 +4525,7 @@ static ScrDyn *scr_array_ctor_call(ScrClosure *closure, ScrDyn *const *args, siz ScrDyn *scr_dyn_array_constructor(void) { if (!scr_array_ctor) { scr_array_ctor = scr_dyn_new_func(scr_closure_new(NULL, 0), scr_array_ctor_call, 1, "native:Array", "Array"); + scr_dyn_fn_seed_prototype(scr_array_ctor, scr_dyn_array_prototype_base()); scr_atexit(scr_array_ctor_cleanup); } return scr_dyn_retain(scr_array_ctor); @@ -4510,6 +4730,399 @@ ScrDyn *scr_bytes_construct(const ScrDyn *callee, const ScrDyn *args, const ScrS return NULL; } +static bool scr_dyn_bytes_named(const char *method, const char *name) { + return strcmp(method, name) == 0; +} + +/* An optional index argument: ToIntegerOrInfinity, or `fallback` when + * absent or undefined. */ +static double scr_dyn_bytes_index_arg(ScrDyn *const *args, size_t argc, size_t index, double fallback) { + if (index >= argc || args[index]->kind == SCR_DYN_UNDEF) return fallback; + double value; + if (!scr_dyn_number_coerce_js(args[index], &value)) return 0; + return isnan(value) ? 0 : trunc(value); +} + +/* The callable-callback gate: " is not a function". */ +static bool scr_dyn_bytes_cb_check(ScrDyn *const *args, size_t argc) { + ScrDyn *cb = argc > 0 ? args[0] : scr_dyn_undefined(); + if (scr_dyn_is_callable(cb)) return true; + bool primitive = cb->kind == SCR_DYN_NUM || cb->kind == SCR_DYN_STR || cb->kind == SCR_DYN_BOOL || + cb->kind == SCR_DYN_UNDEF || cb->kind == SCR_DYN_NULL || cb->kind == SCR_DYN_BIGINT; + ScrStr *text = primitive ? scr_dyn_string_coerce_js(cb) : scr_str_new("#", 9); + if (!text) return false; + ScrJsonBuf b; + scr_jb_init(&b); + scr_jb_write(&b, text->data, text->len); + scr_jb_puts(&b, " is not a function"); + scr_str_release(text); + scr_throw_error(SCR_ERR_TYPE, scr_jb_finish(&b)); + return false; +} + +/* ── %TypedArray%.prototype methods over a checked typed array ────────── + * One dispatch for scr_dyn_invoke's typed array receivers and for the + * method values their reads give, in this always-linked unit. + * Elements are read live at each step: a callback can write the array it + * walks. Results of map, filter and the copying methods take the + * receiver's element kind (and a Buffer's flavor). */ + +static ScrDyn *dyn_bytes_wrap(const ScrDyn *recv, ScrBytes *out) { + ScrDyn *d = recv->buffer ? scr_dyn_new_buffer(out) : scr_dyn_new_bytes(out); + scr_bytes_release(out); + return d; +} + +/* The element at k, or undefined past the view's current end. */ +static ScrDyn *dyn_bytes_item(const ScrBytes *b, size_t k) { + return k < b->len ? scr_dyn_new_num(scr_bytes_get(b, (double)k)) : scr_dyn_retain(scr_dyn_undefined()); +} + +/* callback(value, index, array) with thisArg as `this`. */ +static ScrDyn *dyn_bytes_call(ScrDyn *cb, ScrDyn *this_arg, ScrDyn *const *cbargs, size_t n) { + scr_dyn_this_push_dyn(this_arg); + ScrDyn *r = scr_dyn_call(cb, (ScrDyn **)cbargs, n, "callback"); + scr_dyn_this_pop(); + return r; +} + +/* ToIntegerOrInfinity of a present argument; `fallback` when absent. */ +static bool dyn_bytes_integer_arg(ScrDyn *const *args, size_t argc, size_t i, double fallback, double *out) { + if (i >= argc) { *out = fallback; return true; } + double v; + if (!scr_dyn_number_coerce_js(args[i], &v)) return false; + *out = isnan(v) ? 0 : trunc(v); + return true; +} + +/* SortCompare: the comparator's ToNumber answer (NaN as 0), or the + * numeric order with -0 before +0 and NaN last. */ +static bool dyn_bytes_less_eq(ScrDyn *cmp, double x, double y, bool *ok) { + if (cmp->kind != SCR_DYN_UNDEF) { + ScrDyn *a = scr_dyn_new_num(x), *b = scr_dyn_new_num(y); + ScrDyn *cbargs[2] = { a, b }; + /* The comparator is called with an undefined `this`. */ + scr_dyn_this_push_dyn(scr_dyn_undefined()); + ScrDyn *r = scr_dyn_call(cmp, cbargs, 2, "comparefn"); + scr_dyn_this_pop(); + scr_dyn_release(a); + scr_dyn_release(b); + double v = 0; + if (!r || !scr_dyn_number_coerce_js(r, &v)) { scr_dyn_release(r); *ok = false; return true; } + scr_dyn_release(r); + return isnan(v) || v <= 0; + } + if (isnan(x)) return isnan(y); + if (isnan(y)) return true; + if (x < y) return true; + if (x > y) return false; + return signbit(x) || !signbit(y); +} + +/* A stable merge sort of values[0..n). False with the exception pending. */ +static bool dyn_bytes_sort_values(double *values, size_t n, ScrDyn *cmp) { + if (n < 2) return true; + double *tmp = malloc(n * sizeof *tmp); + if (!tmp) scr_trap("scriptc: out of memory\n"); + bool ok = true; + for (size_t width = 1; width < n && ok; width *= 2) { + for (size_t lo = 0; lo < n && ok; lo += 2 * width) { + size_t mid = lo + width < n ? lo + width : n, hi = lo + 2 * width < n ? lo + 2 * width : n; + size_t i = lo, j = mid, k = lo; + while (i < mid && j < hi && ok) tmp[k++] = dyn_bytes_less_eq(cmp, values[i], values[j], &ok) ? values[i++] : values[j++]; + while (i < mid) tmp[k++] = values[i++]; + while (j < hi) tmp[k++] = values[j++]; + } + if (ok) memcpy(values, tmp, n * sizeof *values); + } + free(tmp); + return ok; +} + +static bool dyn_bytes_comparefn_check(ScrDyn *const *args, size_t argc) { + if (argc == 0 || args[0]->kind == SCR_DYN_UNDEF || scr_dyn_is_callable(args[0])) return true; + static const char message[] = "The comparison function must be either a function or undefined"; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + return false; +} + +static double *dyn_bytes_values(const ScrBytes *b, size_t n) { + double *values = malloc((n ? n : 1) * sizeof *values); + if (!values) scr_trap("scriptc: out of memory\n"); + for (size_t i = 0; i < n; i++) values[i] = scr_bytes_get(b, (double)i); + return values; +} + +ScrDyn *scr_dyn_bytes_method(ScrDyn *recv, const char *method, ScrDyn *const *args, size_t argc, bool *handled) { + ScrBytes *bytes = recv->v.bytes; + size_t len = bytes->len; + *handled = true; + size_t blen = bytes->len; + if (scr_dyn_bytes_named(method, "at")) { + double iD = scr_dyn_bytes_index_arg(args, argc, 0, 0); + if (scr_exc_pending()) return NULL; + double idx = iD < 0 ? (double)blen + iD : iD; + if (idx < 0 || idx >= (double)blen) return scr_dyn_retain(scr_dyn_undefined()); + return scr_dyn_new_num(scr_bytes_get(bytes, idx)); + } + if (scr_dyn_bytes_named(method, "slice") || scr_dyn_bytes_named(method, "subarray")) { + /* subarray and Buffer.slice alias their source. TypedArray.slice + * owns an independent copy; all keep the receiver's Buffer flavor. */ + double startD = scr_dyn_bytes_index_arg(args, argc, 0, 0); + if (scr_exc_pending()) return NULL; + double endD = scr_dyn_bytes_index_arg(args, argc, 1, (double)blen); + if (scr_exc_pending()) return NULL; + ScrBytes *out = recv->buffer || scr_dyn_bytes_named(method, "subarray") + ? scr_bytes_subarray(bytes, startD, endD) : scr_bytes_slice(bytes, startD, endD); + ScrDyn *d = recv->buffer ? scr_dyn_new_buffer(out) : scr_dyn_new_bytes(out); + scr_bytes_release(out); + return d; + } + if (scr_dyn_bytes_named(method, "set")) { + double offset = scr_dyn_bytes_index_arg(args, argc, 1, 0); + if (scr_exc_pending()) return NULL; + scr_bytes_set_from_dyn(bytes, argc ? args[0] : scr_dyn_undefined(), offset); + return scr_exc_pending() ? NULL : scr_dyn_retain(scr_dyn_undefined()); + } + if (scr_dyn_bytes_named(method, "copyWithin")) { + double target = scr_dyn_bytes_index_arg(args, argc, 0, 0); + if (scr_exc_pending()) return NULL; + double start = scr_dyn_bytes_index_arg(args, argc, 1, 0); + if (scr_exc_pending()) return NULL; + double end = scr_dyn_bytes_index_arg(args, argc, 2, (double)blen); + if (scr_exc_pending()) return NULL; + scr_bytes_release(scr_bytes_copy_within(bytes, target, start, end)); + return scr_dyn_retain(recv); + } + if (scr_dyn_bytes_named(method, "fill") && !recv->buffer) { + double value; + if (!scr_dyn_number_coerce_js(argc ? args[0] : scr_dyn_undefined(), &value)) return NULL; + double start = scr_dyn_bytes_index_arg(args, argc, 1, 0); + if (scr_exc_pending()) return NULL; + double end = scr_dyn_bytes_index_arg(args, argc, 2, (double)blen); + if (scr_exc_pending()) return NULL; + scr_bytes_release(scr_bytes_fill_elem(bytes, value, start, end)); + return scr_dyn_retain(recv); + } + if (scr_dyn_bytes_named(method, "join") || (scr_dyn_bytes_named(method, "toString") && !recv->buffer)) { + ScrStr *separator = scr_dyn_bytes_named(method, "join") && argc && args[0]->kind != SCR_DYN_UNDEF + ? scr_dyn_string_coerce_js(args[0]) : scr_str_new(",", 1); + if (scr_exc_pending()) { scr_str_release(separator); return NULL; } + ScrStr *joined = scr_bytes_join(bytes, separator); + scr_str_release(separator); + ScrDyn *out = scr_dyn_new_str(joined); + scr_str_release(joined); + return out; + } + if (scr_dyn_bytes_named(method, "keys") || scr_dyn_bytes_named(method, "values") || scr_dyn_bytes_named(method, "entries")) + return scr_dyn_native_handle_iterator(recv, scr_dyn_bytes_named(method, "keys") ? 1 : scr_dyn_bytes_named(method, "entries") ? 2 : 0); + if (scr_dyn_bytes_named(method, "indexOf") || scr_dyn_bytes_named(method, "lastIndexOf") || scr_dyn_bytes_named(method, "includes")) { + const bool includes = scr_dyn_bytes_named(method, "includes"), last = scr_dyn_bytes_named(method, "lastIndexOf"); + if (len == 0) return includes ? scr_dyn_new_bool(false) : scr_dyn_new_num(-1); + double n; + if (!dyn_bytes_integer_arg(args, argc, 1, last ? (double)len - 1 : 0, &n)) return NULL; + ScrDyn *needle = argc ? args[0] : scr_dyn_undefined(); + const bool number = needle->kind == SCR_DYN_NUM; + const double target = number ? needle->v.num : 0; + if (last) { + if (n == -INFINITY) return scr_dyn_new_num(-1); + double k = n >= 0 ? (n < (double)len - 1 ? n + 0.0 : (double)len - 1) : (double)len + n; + for (; number && k >= 0; k--) + if ((size_t)k < bytes->len && scr_bytes_get(bytes, k) == target) return scr_dyn_new_num(k); + return scr_dyn_new_num(-1); + } + if (n == INFINITY) return includes ? scr_dyn_new_bool(false) : scr_dyn_new_num(-1); + double k = n >= 0 ? n + 0.0 : ((double)len + n < 0 ? 0 : (double)len + n); + for (; k < (double)len; k++) { + /* An element past a shrunk view reads undefined, which includes finds. */ + if ((size_t)k >= bytes->len) { + if (includes && needle->kind == SCR_DYN_UNDEF) return scr_dyn_new_bool(true); + continue; + } + if (!number) continue; + double v = scr_bytes_get(bytes, k); + if (v == target || (includes && isnan(v) && isnan(target))) + return includes ? scr_dyn_new_bool(true) : scr_dyn_new_num(k); + } + return includes ? scr_dyn_new_bool(false) : scr_dyn_new_num(-1); + } + if (scr_dyn_bytes_named(method, "forEach") || scr_dyn_bytes_named(method, "map") || scr_dyn_bytes_named(method, "filter") || scr_dyn_bytes_named(method, "some") || + scr_dyn_bytes_named(method, "every") || scr_dyn_bytes_named(method, "find") || scr_dyn_bytes_named(method, "findIndex") || + scr_dyn_bytes_named(method, "findLast") || scr_dyn_bytes_named(method, "findLastIndex")) { + if (!scr_dyn_bytes_cb_check(args, argc)) return NULL; + ScrDyn *cb = args[0], *this_arg = argc > 1 ? args[1] : scr_dyn_undefined(); + const bool backward = scr_dyn_bytes_named(method, "findLast") || scr_dyn_bytes_named(method, "findLastIndex"); + ScrBytes *mapped = scr_dyn_bytes_named(method, "map") ? scr_bytes_new(bytes->elem, (double)len) : NULL; + double *kept = scr_dyn_bytes_named(method, "filter") ? malloc((len ? len : 1) * sizeof *kept) : NULL; + size_t nkept = 0; + for (size_t step = 0; step < len; step++) { + size_t k = backward ? len - 1 - step : step; + ScrDyn *item = dyn_bytes_item(bytes, k), *index = scr_dyn_new_num((double)k); + ScrDyn *cbargs[3] = { item, index, recv }; + ScrDyn *r = dyn_bytes_call(cb, this_arg, cbargs, 3); + scr_dyn_release(index); + if (!r) { + scr_dyn_release(item); + if (mapped) scr_bytes_release(mapped); + free(kept); + return NULL; + } + if (mapped) { + double v; + bool converted = scr_dyn_number_coerce_js(r, &v); + scr_dyn_release(r); + scr_dyn_release(item); + if (!converted) { scr_bytes_release(mapped); return NULL; } + if (k < mapped->len) scr_bytes_set(mapped, (double)k, v); + continue; + } + bool truthy = scr_dyn_truthy(r); + scr_dyn_release(r); + if (kept) { + if (truthy) kept[nkept++] = item->kind == SCR_DYN_NUM ? item->v.num : NAN; + } else if (truthy && (scr_dyn_bytes_named(method, "find") || scr_dyn_bytes_named(method, "findLast"))) { + return item; + } else if (truthy && (scr_dyn_bytes_named(method, "findIndex") || scr_dyn_bytes_named(method, "findLastIndex"))) { + scr_dyn_release(item); + return scr_dyn_new_num((double)k); + } else if (truthy && scr_dyn_bytes_named(method, "some")) { + scr_dyn_release(item); + return scr_dyn_new_bool(true); + } else if (!truthy && scr_dyn_bytes_named(method, "every")) { + scr_dyn_release(item); + return scr_dyn_new_bool(false); + } + scr_dyn_release(item); + } + if (mapped) return dyn_bytes_wrap(recv, mapped); + if (kept) { + ScrBytes *out = scr_bytes_new(bytes->elem, (double)nkept); + for (size_t i = 0; i < nkept; i++) scr_bytes_set(out, (double)i, kept[i]); + free(kept); + return dyn_bytes_wrap(recv, out); + } + if (scr_dyn_bytes_named(method, "some")) return scr_dyn_new_bool(false); + if (scr_dyn_bytes_named(method, "every")) return scr_dyn_new_bool(true); + if (scr_dyn_bytes_named(method, "findIndex") || scr_dyn_bytes_named(method, "findLastIndex")) return scr_dyn_new_num(-1); + return scr_dyn_retain(scr_dyn_undefined()); /* forEach, find, findLast */ + } + if (scr_dyn_bytes_named(method, "reduce") || scr_dyn_bytes_named(method, "reduceRight")) { + if (!scr_dyn_bytes_cb_check(args, argc)) return NULL; + const bool backward = scr_dyn_bytes_named(method, "reduceRight"); + size_t step = 0; + ScrDyn *acc; + if (argc > 1) acc = scr_dyn_retain(args[1]); + else if (len == 0) { + static const char message[] = "Reduce of empty array with no initial value"; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + return NULL; + } else acc = dyn_bytes_item(bytes, backward ? len - 1 : 0), step = 1; + for (; step < len; step++) { + size_t k = backward ? len - 1 - step : step; + ScrDyn *item = dyn_bytes_item(bytes, k), *index = scr_dyn_new_num((double)k); + ScrDyn *cbargs[4] = { acc, item, index, recv }; + /* The reducer is called with an undefined `this`. */ + scr_dyn_this_push_dyn(scr_dyn_undefined()); + ScrDyn *next = scr_dyn_call(args[0], cbargs, 4, "callback"); + scr_dyn_this_pop(); + scr_dyn_release(index); + scr_dyn_release(item); + scr_dyn_release(acc); + if (!next) return NULL; + acc = next; + } + return acc; + } + if (scr_dyn_bytes_named(method, "reverse")) { + for (size_t lo = 0, hi = len; lo + 1 < hi; lo++, hi--) { + double a = scr_bytes_get(bytes, (double)lo), b = scr_bytes_get(bytes, (double)(hi - 1)); + scr_bytes_set(bytes, (double)lo, b); + scr_bytes_set(bytes, (double)(hi - 1), a); + } + return scr_dyn_retain(recv); + } + if (scr_dyn_bytes_named(method, "sort") || scr_dyn_bytes_named(method, "toSorted")) { + if (!dyn_bytes_comparefn_check(args, argc)) return NULL; + double *values = dyn_bytes_values(bytes, len); + if (!dyn_bytes_sort_values(values, len, argc ? args[0] : scr_dyn_undefined())) { free(values); return NULL; } + ScrBytes *target = scr_dyn_bytes_named(method, "sort") ? bytes : scr_bytes_new(bytes->elem, (double)len); + for (size_t i = 0; i < len && i < target->len; i++) scr_bytes_set(target, (double)i, values[i]); + free(values); + return scr_dyn_bytes_named(method, "sort") ? scr_dyn_retain(recv) : dyn_bytes_wrap(recv, target); + } + if (scr_dyn_bytes_named(method, "toReversed")) { + ScrBytes *out = scr_bytes_new(bytes->elem, (double)len); + for (size_t i = 0; i < len; i++) scr_bytes_set(out, (double)i, scr_bytes_get(bytes, (double)(len - 1 - i))); + return dyn_bytes_wrap(recv, out); + } + if (scr_dyn_bytes_named(method, "with")) { + double rel, value; + if (!dyn_bytes_integer_arg(args, argc, 0, 0, &rel)) return NULL; + double actual = rel >= 0 ? rel : (double)len + rel; + if (!scr_dyn_number_coerce_js(argc > 1 ? args[1] : scr_dyn_undefined(), &value)) return NULL; + if (!(actual >= 0 && actual < (double)bytes->len)) { + static const char message[] = "Invalid typed array index"; + scr_throw_error_msg(SCR_ERR_RANGE, message, sizeof message - 1); + return NULL; + } + ScrBytes *out = scr_bytes_new(bytes->elem, (double)len); + for (size_t i = 0; i < len; i++) scr_bytes_set(out, (double)i, scr_bytes_get(bytes, (double)i)); + scr_bytes_set(out, actual, value); + return dyn_bytes_wrap(recv, out); + } + *handled = false; + return NULL; +} + +/* A %TypedArray%.prototype method read as a value: it calls the method on + * its `this`, which must be a typed array. */ +static ScrDyn *dyn_bytes_method_value_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) { + ScrStr *method = scr_box_get_ref(closure->caps[0]); + ScrDyn *receiver = scr_dyn_this_get(); + ScrDyn *result = NULL; + if (receiver->kind == SCR_DYN_BYTES && !receiver->v.bytes->is_data_view) { + bool handled; + result = scr_dyn_bytes_method(receiver, method->data, args, argc, &handled); + if (!handled) { + ScrJsonBuf b; + scr_jb_init(&b); + scr_jb_puts(&b, "'TypedArray.prototype."); + scr_jb_puts(&b, method->data); + scr_jb_puts(&b, "' through a method value is not supported yet"); + scr_throw_error(SCR_ERR_ERROR, scr_jb_finish(&b)); + } + } else { + static const char message[] = "this is not a typed array."; + scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1); + } + scr_dyn_release(receiver); + scr_str_release(method); + return result; +} + +static SCR_TL ScrDyn *dyn_bytes_method_values; + +static void dyn_bytes_method_values_cleanup(void) { + scr_dyn_release(dyn_bytes_method_values); + dyn_bytes_method_values = NULL; +} + +static ScrDyn *scr_dyn_bytes_method_value(const ScrStr *name, size_t arity) { + if (!dyn_bytes_method_values) { + dyn_bytes_method_values = scr_dyn_new_obj_null_proto(); + scr_atexit(dyn_bytes_method_values_cleanup); + } + ScrDyn *value = scr_dyn_obj_get(dyn_bytes_method_values, name->data, name->len); + if (!value) { + ScrClosure *closure = scr_closure_new(NULL, 1); + closure->caps[0] = scr_box_new(SCR_BOX_STR); + scr_box_set_ref(closure->caps[0], scr_str_retain((ScrStr *)name)); + value = scr_dyn_new_func(closure, dyn_bytes_method_value_call, arity, "native:TypedArray.prototype", name->data); + scr_dyn_obj_set(dyn_bytes_method_values, name->data, name->len, value); /* the table owns it */ + } + return scr_dyn_retain(value); +} + /* Shared view metadata and indexed reads for both compiler backends. */ ScrDyn *scr_dyn_bytes_key_get(const ScrDyn *value, const ScrStr *key) { ScrBytes *bytes = value->v.bytes; @@ -4550,6 +5163,18 @@ ScrDyn *scr_dyn_bytes_key_get(const ScrDyn *value, const ScrStr *key) { } if (digits && index < bytes->len) return scr_dyn_new_num(scr_bytes_get(bytes, (double)index)); } + /* %TypedArray%.prototype methods, with their lengths. */ + static const struct { const char *name; size_t arity; } methods[] = { + {"at", 1}, {"copyWithin", 2}, {"entries", 0}, {"every", 1}, {"fill", 1}, {"filter", 1}, + {"find", 1}, {"findIndex", 1}, {"findLast", 1}, {"findLastIndex", 1}, {"forEach", 1}, + {"includes", 1}, {"indexOf", 1}, {"join", 1}, {"keys", 0}, {"lastIndexOf", 1}, {"map", 1}, + {"reduce", 1}, {"reduceRight", 1}, {"reverse", 0}, {"set", 1}, {"slice", 2}, {"some", 1}, + {"sort", 1}, {"subarray", 2}, {"toLocaleString", 0}, {"toReversed", 0}, {"toSorted", 1}, + {"toString", 0}, {"values", 0}, {"with", 2}, + }; + for (size_t i = 0; i < sizeof methods / sizeof methods[0]; i++) + if (key->len == strlen(methods[i].name) && memcmp(key->data, methods[i].name, key->len) == 0) + return scr_dyn_bytes_method_value(key, methods[i].arity); return scr_dyn_retain(scr_dyn_undefined()); } @@ -5527,6 +6152,16 @@ static ScrDyn *scr_dyn_fn_properties(const ScrDyn *function) { return (ScrDyn *)scr_box_get_ref(owner->props); } +void scr_dyn_fn_seed_prototype(ScrDyn *function, ScrDyn *prototype) { + ScrDyn *table = scr_dyn_fn_properties(function); + scr_dyn_obj_set(table, "prototype", 9, prototype); + ScrDynEntry *entry = scr_dyn_find_entry(table, "prototype", 9); + entry->writable = false; + entry->enumerable = false; + entry->configurable = false; + scr_dyn_release(table); +} + ScrDyn *scr_dyn_function_properties(const ScrDyn *function) { return scr_dyn_fn_properties(function); } ScrDyn *scr_dyn_class_inherit(ScrDyn *constructor, ScrDyn *base) { @@ -5966,7 +6601,18 @@ static ScrDyn *scr_native_iterator_value(ScrNativeIterator *iterator, bool *done } } } else if (items->kind == SCR_DYN_BYTES) { - value = scr_dyn_new_num(scr_bytes_get(items->v.bytes, iterator->index++)); + /* keys(), values() and entries() of a typed array. */ + double index = iterator->index++; + if (iterator->selection == 1) value = scr_dyn_new_num(index); + else { + value = scr_dyn_new_num(scr_bytes_get(items->v.bytes, index)); + if (iterator->selection == 2) { + ScrDyn *entry = scr_dyn_new_arr(); + scr_dyn_arr_push(entry, scr_dyn_new_num(index)); + scr_dyn_arr_push(entry, value); + value = entry; + } + } } else { ScrStr *point = scr_str_cp_at(items->v.str, iterator->index); iterator->index += scr_str_utf16_len(point); @@ -7927,6 +8573,12 @@ typedef struct { * or NULL. The code slot holds only strings, and a subclass's typed view * rebuilds its properties from the slots on every read. */ ScrDyn *code; + /* The prototype a view built from the error's fields starts with + * (scr_error_dyn_fields: the holder of its default name and message, or + * none), retained so that no later object takes its address. Only such a + * view sets `fields_view`. */ + ScrDyn *view_prototype; + bool fields_view; } ScrErrDynEnt; static SCR_TL ScrErrDynEnt *scr_errdyn_cache = NULL; @@ -8031,6 +8683,7 @@ static void scr_errdyn_sweep(void) { scr_error_release(dead[i].err); scr_errdyn_release_node(dead[i].dyn); scr_dyn_release(dead[i].code); + scr_dyn_release(dead[i].view_prototype); } free(dead); } @@ -8052,6 +8705,8 @@ static void scr_errdyn_append(ScrError *e, ScrDyn *d) { scr_errdyn_cache[scr_errdyn_n].err = scr_error_retain(e); scr_errdyn_cache[scr_errdyn_n].dyn = scr_dyn_retain(d); scr_errdyn_cache[scr_errdyn_n].code = NULL; + scr_errdyn_cache[scr_errdyn_n].view_prototype = NULL; + scr_errdyn_cache[scr_errdyn_n].fields_view = false; scr_errdyn_n++; if (scr_errdyn_n * 2 > scr_errdyn_slots) { free(scr_errdyn_by_err); @@ -8108,6 +8763,7 @@ static void scr_errdyn_teardown(void) { scr_error_release(cache[i].err); scr_errdyn_release_node(cache[i].dyn); scr_dyn_release(cache[i].code); + scr_dyn_release(cache[i].view_prototype); } free(cache); } @@ -8211,6 +8867,19 @@ static void scr_error_dyn_add_stack(ScrDyn *d) { entry->enumerable = false; } +/* Whether `object` is the view scr_error_dyn_fields built for an error + * created as an Error (not a subclass or another error kind) and its + * prototype is still the one the view started with. Such an error's + * prototype is Error.prototype. */ +static bool scr_dyn_error_view_on_error_prototype(const ScrDyn *object) { + if (object->null_proto) return false; + size_t hit = scr_errdyn_find(object, false); + if (hit == SIZE_MAX) return false; + const ScrErrDynEnt *ent = &scr_errdyn_cache[hit]; + return ent->fields_view && object->prototype == ent->view_prototype && + ent->err->vt == &scr_error_vts[SCR_ERR_ERROR]; +} + ScrDyn *scr_error_dyn_fields(const ScrError *e) { ScrDyn *d = scr_dyn_new_obj(); scr_dyn_obj_set(d, "%error", 6, scr_dyn_new_bool(true)); /* the checked-dynamic tree's error marker */ @@ -8330,6 +8999,102 @@ void scr_error_dyn_place_name(ScrDyn *view, const char *after, size_t after_len) view->v.obj.index = NULL; } +static size_t scr_dyn_entry_index(const ScrDyn *object, const char *key, size_t key_len) { + for (size_t i = 0; i < object->v.obj.len; i++) { + const ScrDynEntry *entry = &object->v.obj.entries[i]; + if (entry->key_len == key_len && memcmp(entry->key, key, key_len) == 0) return i; + } + return SIZE_MAX; +} + +/* Whether bag entry b is one of the entries Error's constructor creates + * before the instance's class fields: `stack`, a hidden entry (a key + * starting with '%'), and a `message` that directly follows them. */ +static bool scr_error_bag_constructed(const ScrDyn *bag, size_t b) { + for (size_t i = 0; i <= b; i++) { + const ScrDynEntry *entry = &bag->v.obj.entries[i]; + bool constructed = (entry->key_len == 5 && memcmp(entry->key, "stack", 5) == 0) || + (entry->key_len > 0 && entry->key[0] == '%') || + (entry->key_len == 7 && memcmp(entry->key, "message", 7) == 0); + if (!constructed) return false; + } + return true; +} + +/* The view index at which bag entry b, now at `from`, belongs: after the + * nearest earlier bag property the view has. An entry created after + * construction (any `name` placed here, since no constructor of the class + * sets it, and a `message` that is not one of Error's constructor entries) + * also follows the class fields, which live in slots and not in the bag: it + * passes over the constructor's entries and over a `name` the construction + * set, and without another earlier property goes before the nearest later + * one the view has, or stays where the view put it. A `message` Error's + * constructor created follows the nearest earlier entry, or goes first. */ +static size_t scr_error_bag_place(const ScrDyn *view, const ScrDyn *bag, size_t b, bool name, + bool name_placed, size_t from) { + bool late = name || !scr_error_bag_constructed(bag, b); + for (size_t p = b; p-- > 0;) { + const ScrDynEntry *anchor = &bag->v.obj.entries[p]; + if (late && scr_error_bag_constructed(bag, p)) break; + if (late && name_placed && anchor->key_len == 4 && memcmp(anchor->key, "name", 4) == 0) continue; + size_t after = scr_dyn_entry_index(view, anchor->key, anchor->key_len); + if (after != SIZE_MAX) return after < from ? after + 1 : after; + } + if (!late) return 0; + for (size_t p = b + 1; p < bag->v.obj.len; p++) { + size_t before = scr_dyn_entry_index(view, bag->v.obj.entries[p].key, bag->v.obj.entries[p].key_len); + if (before != SIZE_MAX) return before > from ? before - 1 : before; + } + return from; +} + +/* The bag holds the view as it was last committed, in the order its + * properties were created: zod's error factory assigns `name` and then + * defines `message`, and Node lists them in that order. The slots rebuild + * both at fixed positions (scr_error_dyn_fields, scr_error_dyn_place_name), + * so each one present in the bag moves to follow the property it follows + * there. A typed write to `name` or `message` reaches only the slot, so a + * data property takes the slot's value. */ +void scr_error_dyn_follow_bag(ScrDyn *view, const ScrDyn *bag, const ScrError *e, bool name_placed) { + if (!bag || bag->kind != SCR_DYN_OBJ || view->kind != SCR_DYN_OBJ) return; + static const struct { const char *key; size_t len; } slots[] = {{"name", 4}, {"message", 7}}; + for (size_t s = 0; s < 2; s++) { + bool name = s == 0; + if (!(name ? e->name_present : e->message_present)) continue; + size_t at = scr_dyn_entry_index(view, slots[s].key, slots[s].len); + if (at == SIZE_MAX || view->v.obj.entries[at].accessor) continue; + ScrDyn *value = scr_dyn_new_str(name ? e->name : e->message); + scr_dyn_region_store(view, value); + ScrDyn *old = view->v.obj.entries[at].value; + view->v.obj.entries[at].value = value; + scr_dyn_release(old); + } + bool moved = false; + for (size_t b = 0; b < bag->v.obj.len; b++) { + const ScrDynEntry *bag_entry = &bag->v.obj.entries[b]; + bool slot = (bag_entry->key_len == 4 && memcmp(bag_entry->key, "name", 4) == 0) || + (bag_entry->key_len == 7 && memcmp(bag_entry->key, "message", 7) == 0); + bool name = bag_entry->key_len == 4; + /* A `name` the class's construction sets is in place already. */ + if (!slot || (name && name_placed)) continue; + size_t from = scr_dyn_entry_index(view, bag_entry->key, bag_entry->key_len); + if (from == SIZE_MAX) continue; + size_t to = scr_error_bag_place(view, bag, b, name, name_placed, from); + if (to == from) continue; + ScrDynEntry *entries = view->v.obj.entries; + ScrDynEntry entry = entries[from]; + if (to < from) memmove(&entries[to + 1], &entries[to], (from - to) * sizeof *entries); + else memmove(&entries[from], &entries[from + 1], (to - from) * sizeof *entries); + entries[to] = entry; + moved = true; + } + if (moved) { + SCR_JS_SHAPE_RESET(view); + free(view->v.obj.index); + view->v.obj.index = NULL; + } +} + ScrDyn *scr_dyn_from_error(const ScrError *e) { size_t hit = scr_errdyn_find(e, true); if (hit != SIZE_MAX) return scr_dyn_retain(scr_errdyn_cache[hit].dyn); @@ -8340,8 +9105,14 @@ ScrDyn *scr_dyn_from_error(const ScrError *e) { break; } } + bool fields_view = d == NULL; if (!d) d = scr_error_dyn_fields(e); scr_errdyn_append((ScrError *)e, d); + if (fields_view) { + ScrErrDynEnt *ent = &scr_errdyn_cache[scr_errdyn_n - 1]; + ent->fields_view = true; + ent->view_prototype = d->prototype ? scr_dyn_retain(d->prototype) : NULL; + } return d; } @@ -12465,6 +13236,13 @@ ScrDyn *scr_dyn_fn_get(const ScrDyn *d, const char *key, size_t key_len) { ScrClosure *owner = scr_closure_identity(d->v.fn.clo); if (d->v.fn.class_obj && d->v.fn.class_obj->static_data && !owner->props) owner->props = scr_box_retain(d->v.fn.class_obj->static_data); + if (d->v.fn.thunk == scr_function_constructor_call && key_len == 9 && !memcmp(key, "prototype", 9)) { + /* A function's `constructor.prototype`: Function.prototype has no value + * here, and undefined would be a wrong answer. */ + static const char function_prototype[] = "Function.prototype through a constructor value is not supported yet"; + scr_throw_error_msg_code(SCR_ERR_ERROR, function_prototype, sizeof function_prototype - 1, "SC2020"); + return NULL; + } if (!d->v.fn.class_obj && key_len == 9 && !memcmp(key, "prototype", 9) && !owner->props) { if (owner->function_kind & 1) { static const char message[] = "Native generator function prototypes have no lowering"; @@ -13241,6 +14019,20 @@ ScrDyn *scr_dyn_get_own_property_names(const ScrDyn *value) { } if (value->kind == SCR_DYN_OBJ) { ScrDyn *keys = scr_dyn_obj_own_keys(value); + if (value == scr_builtin_object_prototype) { + /* Object.prototype's builtin members, in Node's order. */ + static const char *const names[] = { + "constructor", "__defineGetter__", "__defineSetter__", "hasOwnProperty", + "__lookupGetter__", "__lookupSetter__", "isPrototypeOf", "propertyIsEnumerable", + "toString", "valueOf", "__proto__", "toLocaleString" + }; + ScrDyn *all = scr_dyn_new_arr(); + for (size_t i = 0; i < sizeof names / sizeof names[0]; i++) + scr_dyn_arr_push(all, scr_dyn_objwalk_key(names[i], strlen(names[i]))); + for (size_t i = 0; i < keys->v.arr.len; i++) scr_dyn_arr_push(all, scr_dyn_retain(keys->v.arr.items[i])); + scr_dyn_release(keys); + return all; + } if (!scr_dyn_obj_get(value, "%error", 6)) return keys; /* The checked-dynamic tree's error marker is not a property. */ ScrDyn *names = scr_dyn_new_arr(); @@ -13266,10 +14058,18 @@ ScrDyn *scr_dyn_get_own_property_names(const ScrDyn *value) { } if (value->kind != SCR_DYN_BYTES) scr_dyn_arr_push(keys, scr_dyn_objwalk_key("length", 6)); + bool array_prototype = value == scr_builtin_array_prototype; + if (array_prototype) scr_dyn_arr_push(keys, scr_dyn_objwalk_key("constructor", 11)); if (value->kind == SCR_DYN_ARR && value->v.arr.properties) { ScrDyn *properties = scr_dyn_obj_own_keys(value->v.arr.properties); - for (size_t i = 0; i < properties->v.arr.len; i++) - scr_dyn_arr_push(keys, scr_dyn_retain(properties->v.arr.items[i])); + for (size_t i = 0; i < properties->v.arr.len; i++) { + ScrDyn *name = properties->v.arr.items[i]; + /* A constructor stored on Array.prototype keeps the position above. */ + if (array_prototype && name->kind == SCR_DYN_STR && name->v.str->len == 11 && + memcmp(name->v.str->data, "constructor", 11) == 0) + continue; + scr_dyn_arr_push(keys, scr_dyn_retain(name)); + } scr_dyn_release(properties); } return keys; @@ -14352,10 +15152,16 @@ bool scr_dyn_has_own(const ScrDyn *v, const ScrStr *key) { if (v->kind == SCR_DYN_OBJ) { + /* Object.prototype's builtin members are its own properties (zod's + * isPlainObject asks whether the prototype has its own isPrototypeOf). */ + if (v == scr_builtin_object_prototype && scr_dyn_object_proto_name(key)) return true; return scr_dyn_obj_get(v, key->data, key->len) != NULL; } if (v->kind == SCR_DYN_ARR) { if (key->len == 6 && memcmp(key->data, "length", 6) == 0) return true; + /* Array.prototype's own constructor (its methods are table entries). */ + if (v == scr_builtin_array_prototype && key->len == 11 && memcmp(key->data, "constructor", 11) == 0) + return true; if (v->v.arr.properties && scr_dyn_obj_get(v->v.arr.properties, key->data, key->len)) return true; if (!scr_dyn_canonical_own_index(key, v->v.arr.len)) return false; size_t index = 0; diff --git a/packages/runtime/src/scr_lib.c b/packages/runtime/src/scr_lib.c index 28e1bda07..ba77f988c 100644 --- a/packages/runtime/src/scr_lib.c +++ b/packages/runtime/src/scr_lib.c @@ -1078,6 +1078,10 @@ bool scr_fs_path_ok(const ScrStr *path, const char *name) { return false; } +void scr_fs_check_path(ScrStr *path, ScrStr *name) { + (void)scr_fs_path_ok(path, name->data); +} + void scr_process_load_env_file(const ScrDyn *value) { ScrStr *path; if (value->kind == SCR_DYN_UNDEF || value->kind == SCR_DYN_NULL) path = scr_str_new("./.env", 6); diff --git a/packages/runtime/src/scr_lib.h b/packages/runtime/src/scr_lib.h index 95f67044a..fa447ff41 100644 --- a/packages/runtime/src/scr_lib.h +++ b/packages/runtime/src/scr_lib.h @@ -409,6 +409,9 @@ void scr_fs_invalid_named_path(const ScrDyn *value, const ScrStr *path, const ch /* A string path argument: false after throwing Node's ERR_INVALID_ARG_VALUE * when it holds a null byte (`name` is the argument's name). */ bool scr_fs_path_ok(const ScrStr *path, const char *name); +/* scr_fs_path_ok as a statement: getValidatedPath's null-byte check on a + * path the call validates before converting a later URL path. */ +void scr_fs_check_path(ScrStr *path, ScrStr *name); void scr_fs_futimes(double fd, double atime, double mtime); void scr_fs_link(ScrStr *source, ScrStr *dest); void scr_fs_symlink(ScrStr *target, ScrStr *destination, int kind); diff --git a/packages/runtime/src/scr_object.c b/packages/runtime/src/scr_object.c index 7cafbeca3..2f47a1c7b 100644 --- a/packages/runtime/src/scr_object.c +++ b/packages/runtime/src/scr_object.c @@ -33,6 +33,8 @@ ScrClassObj *scr_classobj_new(const ScrClassObj *template, size_t ncaps) { c->length = template->length; c->prototype_data = NULL; c->static_data = NULL; + c->base_name = template->base_name; + c->own_static_fields = template->own_static_fields; scr_obj_alloc_note(); return c; } diff --git a/packages/runtime/src/scr_url.c b/packages/runtime/src/scr_url.c index 67de82471..09ccb87fe 100644 --- a/packages/runtime/src/scr_url.c +++ b/packages/runtime/src/scr_url.c @@ -6,7 +6,7 @@ * against Node by the differential corpus: * - scheme lowercasing; "Invalid URL" TypeError on schemeless input * - special schemes (http/https/ws/wss/ftp/file): authority parsing with - * host lowercasing, default-port removal (leading zeros stripped), + * percent-decoded, lowercased hosts, default-port removal (leading zeros stripped), * canonical bracketed IPv6 literals, * backslash-as-slash, and any run of leading slashes tolerated * (http:foo.com works); file: takes an authority only after exactly @@ -17,13 +17,14 @@ * (space, quotes, angle brackets, braces, non-ASCII UTF-8 bytes, ...); * existing %-sequences pass through verbatim (no decode, no case * normalization — like Node) - * - non-special schemes: "//" parses an authority (host case preserved), - * a single "/" roots a normalized path, anything else is an OPAQUE - * path kept verbatim (data:text/plain,hi there) + * - non-special schemes: "//" parses an authority (an opaque host, + * case preserved, C0-encoded), a single "/" roots a normalized path, + * anything else is an OPAQUE path with the C0 control set encoded + * (data:text/plain,hi there) * - * DOCUMENTED DIVERGENCES (SEMANTICS.md): non-ASCII and %-escaped hosts are - * rejected with "Invalid URL" (no IDNA/punycode), and opaque paths skip - * the spec's C0-encode pass (kept verbatim). + * DOCUMENTED DIVERGENCE: a special host that holds non-ASCII text after + * percent-decoding is rejected with "Invalid URL" (no UTS #46 processing), + * and "xn--" labels are kept without Punycode validation. * * Failures THROW catchable TypeErrors through the exception cell with * Node's messages; callers are compiler-emitted pending checks. */ @@ -176,7 +177,7 @@ static bool enc_query(unsigned char c, bool special) { } static bool enc_path(unsigned char c) { - return enc_query(c, false) || c == '?' || c == '`' || c == '{' || c == '}'; + return enc_query(c, false) || c == '?' || c == '^' || c == '`' || c == '{' || c == '}'; } static bool enc_userinfo(unsigned char c) { @@ -392,17 +393,58 @@ static bool url_ipv4_parse(const char *s, size_t n, UrlBuf *out) { return true; } -/* Shared constructor/setter host parsing keeps the existing ASCII-host - * boundary and canonical IPv6 serialization in both execution tiers. A - * special host that ends in a number is an IPv4 address: it serializes - * as dotted decimal, or the URL is invalid. */ +/* Byte classes for the host parser: URL_FORBIDDEN_HOST marks the URL + * Standard's forbidden host code points (opaque hosts), URL_FORBIDDEN_DOMAIN + * its forbidden domain code points (those plus the C0 controls, '%' and + * U+007F) and every non-ASCII byte, which a special host cannot hold + * without UTS #46 processing. */ +enum { URL_FORBIDDEN_HOST = 1, URL_FORBIDDEN_DOMAIN = 2 }; + +static const unsigned char url_host_byte_class[256] = { + 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 3, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 0, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 3, + 3, 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, 3, 3, 3, 3, 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, 3, 0, 0, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +}; + +static bool enc_c0_control(unsigned char c) { + return c < 0x20 || c > 0x7E; +} + +static int hex_val(char c) { + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + return -1; +} + +/* The URL Standard's host parser for the constructor and the setters, + * with canonical IPv6 serialization: + * - a non-special (opaque) host refuses forbidden host code points and + * percent-encodes the C0 control set; + * - a special host is percent-decoded, lowercased, refused when it holds a + * forbidden domain code point, and serialized as dotted decimal when it + * ends in a number (or refused when that number is invalid). + * Divergence: a special host that decodes to non-ASCII needs UTS #46 + * processing, which this unit does not link, so it is refused; "xn--" + * labels are kept without Punycode validation. */ static bool parse_host(const char *hp, size_t host_len, bool special, bool is_file, ScrStr **host) { bool ipv6 = host_len > 0 && hp[0] == '['; size_t ipv6_end = host_len ? host_len - 1 : 0; if (ipv6 && (host_len < 3 || hp[ipv6_end] != ']')) return false; - /* Validate + lowercase (special) the host. Divergence: non-ASCII and - * %-escapes (IDNA territory) are rejected outright. */ UrlBuf hb; ub_init(&hb); if (ipv6) { @@ -410,22 +452,37 @@ static bool parse_host(const char *hp, size_t host_len, bool special, bool is_fi free(hb.data); return false; } - } else { + *host = ub_take(&hb); + return true; + } + if (!special) { for (size_t i = 0; i < host_len; i++) { unsigned char c = (unsigned char)hp[i]; - if (c >= 0x80 || c == '%' || c == ':' || c == '[' || c == ']' || - c <= 0x20 || c == '#' || c == '/' || c == '<' || c == '>' || - c == '?' || c == '@' || c == '\\' || c == '^' || c == '|') { + if (url_host_byte_class[c] & URL_FORBIDDEN_HOST) { free(hb.data); return false; } - if (special && c >= 'A' && c <= 'Z') { - c = (unsigned char)(c - 'A' + 'a'); - } - ub_push(&hb, (char)c); + ub_push_encoded(&hb, c, enc_c0_control); } + *host = ub_take(&hb); + return true; } - if (!ipv6 && special && url_ends_in_number(hb.data, hb.len)) { + for (size_t i = 0; i < host_len; i++) { + unsigned char c = (unsigned char)hp[i]; + int hi, lo; + if (c == '%' && i + 2 < host_len && (hi = hex_val(hp[i + 1])) >= 0 && + (lo = hex_val(hp[i + 2])) >= 0) { + c = (unsigned char)(hi * 16 + lo); + i += 2; + } + if (url_host_byte_class[c] & URL_FORBIDDEN_DOMAIN) { + free(hb.data); + return false; + } + if (c >= 'A' && c <= 'Z') c = (unsigned char)(c - 'A' + 'a'); + ub_push(&hb, (char)c); + } + if (url_ends_in_number(hb.data, hb.len)) { UrlBuf ip; ub_init(&ip); bool ok = url_ipv4_parse(hb.data, hb.len, &ip); @@ -438,7 +495,7 @@ static bool parse_host(const char *hp, size_t host_len, bool special, bool is_fi } /* file: "localhost" normalizes to "" at parse time (Node). */ if (is_file && hb.len == 9 && memcmp(hb.data, "localhost", 9) == 0) hb.len = 0; - if (hb.len == 0 && special && !is_file) { + if (hb.len == 0 && !is_file) { free(hb.data); return false; /* http:// — special non-file needs a host */ } @@ -481,6 +538,13 @@ static bool parse_authority(const char *raw, size_t len, bool special, bool is_f } const char *hp = at >= 0 ? raw + at + 1 : raw; size_t hp_len = at >= 0 ? len - (size_t)at - 1 : len; + /* Credentials need a host. A file: authority is a host alone, so its + * '@' and ':' reach the host parser, which refuses them. */ + if (at >= 0 && hp_len == 0) return false; + if (is_file) { + *port = scr_str_new("", 0); + return at < 0 && parse_host(hp, hp_len, special, is_file, host); + } /* host[:port], with IPv6 literals bracketed per WHATWG. */ long colon = -1; size_t host_len = hp_len; @@ -500,6 +564,7 @@ static bool parse_authority(const char *raw, size_t len, bool special, bool is_f } host_len = colon >= 0 ? (size_t)colon : hp_len; } + if (colon >= 0 && host_len == 0) return false; if (!parse_host(hp, host_len, special, is_file, host)) return false; /* Port: digits only, leading zeros stripped, defaults dropped. */ UrlBuf pb; @@ -700,11 +765,18 @@ ScrUrl *scr_url_new(ScrStr *input) { port = scr_str_new("", 0); path = parse_rooted_path(body, body_len, false); } else { - /* Opaque path — kept verbatim (divergence: the spec C0-encodes). */ + /* Opaque path: the C0 control set is percent-encoded, and a space + * right before a query or fragment becomes %20. */ userinfo = scr_str_new("", 0); host = scr_str_new("", 0); port = scr_str_new("", 0); - path = scr_str_new(body, body_len); + UrlBuf ob; + ub_init(&ob); + bool trailing_space = qmark < rest_len && body_len > 0 && body[body_len - 1] == ' '; + size_t kept = trailing_space ? body_len - 1 : body_len; + for (size_t i = 0; i < kept; i++) ub_push_encoded(&ob, (unsigned char)body[i], enc_c0_control); + if (trailing_space) ub_append(&ob, "%20", 3); + path = ub_take(&ob); } /* Query and fragment, encoded and stored WITH their sigils. */ @@ -823,18 +895,22 @@ ScrUrl *scr_url_new_base(ScrStr *input, ScrStr *base_input) { bool drive = file && path_len >= 2 && url_drive_letter(raw, 2) && (path_len == 2 || raw[2] == '/' || raw[2] == '\\'); if (base->has_authority) { + /* A drive letter relative to a file: base keeps the base's host. */ ub_append(&absolute, "//", 2); - if (!drive) { - if (base->userinfo->len) { - ub_append(&absolute, base->userinfo->data, base->userinfo->len); - ub_push(&absolute, '@'); - } - ub_append(&absolute, base->host->data, base->host->len); - if (base->port->len) { - ub_push(&absolute, ':'); - ub_append(&absolute, base->port->data, base->port->len); - } + if (base->userinfo->len) { + ub_append(&absolute, base->userinfo->data, base->userinfo->len); + ub_push(&absolute, '@'); } + ub_append(&absolute, base->host->data, base->host->len); + if (base->port->len) { + ub_push(&absolute, ':'); + ub_append(&absolute, base->port->data, base->port->len); + } + } else if (!opaque) { + /* A host-less base path can start with "//"; the "/." prefix keeps + * the resolved path from reparsing as an authority (dot-segment + * removal drops it). */ + ub_append(&absolute, "/.", 2); } if (!path_len) { ub_append(&absolute, base->path->data, base->path->len); @@ -1279,13 +1355,6 @@ void scr_url_set_checked(ScrUrl *u, ScrStr *field, const ScrDyn *value) { /* ── the file-URL bridge ─────────────────────────────────────────────── */ -static int hex_val(char c) { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - return -1; -} - static bool url_file_scheme(ScrUrl *u) { if (u->scheme->len == 4 && memcmp(u->scheme->data, "file", 4) == 0) return true; scr_throw_error_msg_code(SCR_ERR_TYPE, "The URL must be of scheme file", 30, "ERR_INVALID_URL_SCHEME"); @@ -1394,6 +1463,22 @@ ScrStr *scr_url_to_path(ScrUrl *u) { #endif } +/* fs.existsSync and the fs.promises functions convert a URL path inside a + * try and turn its error into false or a rejection: the conversion's result + * as a value, the path string or the error. */ +ScrDyn *scr_url_to_path_value(ScrUrl *u) { + ScrStr *path = scr_url_to_path(u); + if (path) { + ScrDyn *value = scr_dyn_new_str(path); + scr_str_release(path); + return value; + } + ScrCaught *caught = scr_exc_take(); + ScrDyn *error = scr_caught_to_dyn(caught); + scr_caught_release(caught); + return error; +} + /* The string-receiver form parses first (Node accepts URL strings). */ ScrStr *scr_url_str_to_path(ScrStr *input) { ScrUrl *u = scr_url_new(input); @@ -1451,7 +1536,7 @@ static void scr_url_throw_arg_value(const char *reason, ScrStr *value) { * bindingUrl.pathToFileURL does, reusing the parser's rooted-path * machinery (WHATWG dot-segment removal with empty segments preserved, * backslash-as-slash when `backslash_sep`, the enc_path set): the bytes - * Node encodes BEYOND that set ('%', '[', ']', '^', '|' — and '\\' when + * Node encodes BEYOND that set ('%', '[', ']', '^', '|', '~' — and '\\' when * it is a path byte rather than a separator) pre-encode here so the * parser passes them through. */ static ScrStr *scr_url_encode_file_path(const char *raw, size_t len, bool backslash_sep) { @@ -1459,7 +1544,7 @@ static ScrStr *scr_url_encode_file_path(const char *raw, size_t len, bool backsl ub_init(&pre); for (size_t i = 0; i < len; i++) { unsigned char c = (unsigned char)raw[i]; - if (c == '%' || c == '[' || c == ']' || c == '^' || c == '|' || + if (c == '%' || c == '[' || c == ']' || c == '^' || c == '|' || c == '~' || (c == '\\' && !backslash_sep)) { char hex[4]; snprintf(hex, sizeof hex, "%%%02X", c); @@ -1521,24 +1606,30 @@ static ScrUrl *scr_url_from_path_impl(ScrStr *path, bool win32) { scr_str_release(resolved); return NULL; } - /* The URL host parser lowercases ASCII and TERMINATES at the URL - * delimiters '/', '?', '#' (Node feeds the servername through - * set_hostname: "\\\\?\\C:\\x" gets an EMPTY host and stays a - * drive path). No IDNA (documented divergence — Node punycodes - * non-ASCII names), and names with ':' or '%' stay verbatim where - * Node aborts on a native set_hostname assertion. */ - UrlBuf host; - ub_init(&host); + /* The servername goes through the host parser, as Node's hostname + * setter does: it drops tabs and newlines, stops at the URL + * delimiters '/', '?' and '#' + * ("\\\\?\\C:\\x" gets an empty host and stays a drive path), + * and a host it refuses throws ERR_INVALID_URL. */ + UrlBuf name; + ub_init(&name); for (size_t i = prefix; i < (size_t)host_end; i++) { char c = resolved->data[i]; if (c == '/' || c == '?' || c == '#') break; - if (c >= 'A' && c <= 'Z') c = (char)(c + 32); - ub_push(&host, c); + if (c != '\t' && c != '\n' && c != '\r') ub_push(&name, c); + } + ScrStr *host = NULL; + bool valid = parse_host(name.data, name.len, true, true, &host); + free(name.data); + if (!valid) { + scr_str_release(resolved); + scr_url_throw_invalid(); + return NULL; } ScrStr *encoded = scr_url_encode_file_path(resolved->data + host_end, resolved->len - (size_t)host_end, true); scr_str_release(resolved); - return scr_url_new_file(ub_take(&host), encoded); + return scr_url_new_file(host, encoded); } } else { ScrArr *pack = scr_arr_new(SCR_ELEM_STR, 1); @@ -1649,10 +1740,117 @@ static bool scr_native_url_set(void *ptr, const char *key, size_t len, const Scr return true; } +/* util.inspect's view of a URL: the properties Node's URL inspector lists, + * in its order, with the live searchParams object. Past the depth limit + * the inspector returns the URL itself, which util.inspect prints as + * `URL {}` (it has no own properties). */ +static ScrDyn *scr_native_url_inspect_view(void *ptr) { + static const char *const keys[] = {"href", "origin", "protocol", "username", "password", + "host", "hostname", "port", "pathname", "search", + "searchParams", "hash"}; + ScrDyn *view = scr_dyn_new_obj(); + for (size_t i = 0; i < sizeof keys / sizeof keys[0]; i++) { + size_t len = strlen(keys[i]); + scr_dyn_obj_set(view, keys[i], len, scr_native_url_get(ptr, keys[i], len)); + } + return view; +} + +/* Node's urlToHttpOptions over a URL: protocol, hostname (an IPv6 literal + * without its brackets), hash, search, pathname, path (pathname and + * search), href, then port as a number when the URL has one and auth + * (the decoded username and password) when it has credentials. */ +ScrDyn *scr_url_to_http_options(ScrUrl *u) { + ScrDyn *options = scr_dyn_new_obj_null_proto(); + ScrStr *pathname = scr_url_pathname(u); + ScrStr *search = scr_url_search(u); + ScrStr *hostname = scr_url_hostname(u); + ScrStr *port = scr_url_port(u); + ScrStr *username = scr_url_username(u); + ScrStr *password = scr_url_password(u); + ScrStr *auth = NULL; + if (username->len || password->len) { + ScrStr *user = scr_str_decode_uri_component(username); + ScrStr *pass = user ? scr_str_decode_uri_component(password) : NULL; + if (pass) { + UrlBuf b; + ub_init(&b); + ub_append(&b, user->data, user->len); + ub_push(&b, ':'); + ub_append(&b, pass->data, pass->len); + auth = ub_take(&b); + } + scr_str_release(user); + scr_str_release(pass); + if (!auth) { + scr_str_release(pathname); + scr_str_release(search); + scr_str_release(hostname); + scr_str_release(port); + scr_str_release(username); + scr_str_release(password); + scr_dyn_release(options); + return NULL; + } + } +#define PUT_STR(key, value) \ + do { \ + ScrStr *text_ = (value); \ + scr_dyn_obj_set(options, key, sizeof key - 1, scr_dyn_new_str(text_)); \ + scr_str_release(text_); \ + } while (0) + PUT_STR("protocol", scr_url_protocol(u)); + if (hostname->len >= 2 && hostname->data[0] == '[') + PUT_STR("hostname", scr_str_new(hostname->data + 1, hostname->len - 2)); + else + PUT_STR("hostname", scr_str_retain(hostname)); + PUT_STR("hash", scr_url_hash(u)); + PUT_STR("search", scr_str_retain(search)); + PUT_STR("pathname", scr_str_retain(pathname)); + UrlBuf path; + ub_init(&path); + ub_append(&path, pathname->data, pathname->len); + ub_append(&path, search->data, search->len); + PUT_STR("path", ub_take(&path)); + PUT_STR("href", scr_url_href(u)); + if (port->len) { + double number = 0; + for (size_t i = 0; i < port->len; i++) number = number * 10 + (port->data[i] - '0'); + scr_dyn_obj_set(options, "port", 4, scr_dyn_new_num(number)); + } + if (auth) PUT_STR("auth", auth); +#undef PUT_STR + scr_str_release(pathname); + scr_str_release(search); + scr_str_release(hostname); + scr_str_release(port); + scr_str_release(username); + scr_str_release(password); + return options; +} + +ScrDyn *scr_url_to_http_options_dyn(const ScrDyn *value) { + if (scr_dyn_native_url_is(value)) return scr_url_to_http_options(value->v.handle.ptr); + if (!value || value->kind <= SCR_DYN_STR || value->kind == SCR_DYN_UNDEF || + value->kind == SCR_DYN_BIGINT || value->kind == SCR_DYN_SYMBOL) { + scr_dyn_arg_type_fail("url", "of type object", value); + return NULL; + } + static const char message[] = "url.urlToHttpOptions of an object that is not a URL is not supported yet"; + scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020"); + return NULL; +} + ScrDyn *scr_dyn_native_url(ScrUrl *value) { static const ScrDynHandleOps ops = { - "URL", &scr_url_retain_v, &scr_url_release_v, &scr_native_url_invoke, - &scr_native_url_get, &scr_native_url_set, NULL, NULL, + .cls = "URL", + .retain = &scr_url_retain_v, + .release = &scr_url_release_v, + .invoke = &scr_native_url_invoke, + .get = &scr_native_url_get, + .set = &scr_native_url_set, + .inspect_view = &scr_native_url_inspect_view, + .inspect_view_nested = true, }; scr_dyn_handle_install(SCR_DYNH_URL, &ops); return scr_dyn_new_handle(value, SCR_DYNH_URL); diff --git a/packages/runtime/src/scr_url.h b/packages/runtime/src/scr_url.h index 05e5702bb..c7c9c63c8 100644 --- a/packages/runtime/src/scr_url.h +++ b/packages/runtime/src/scr_url.h @@ -41,6 +41,12 @@ ScrStr *scr_url_href(ScrUrl *u); /* +1; also toString() */ void scr_url_set(ScrUrl *u, ScrStr *field, ScrStr *value); /* borrowed; href may throw */ bool scr_url_set_component(ScrUrl *u, ScrStr *field, ScrStr *value); /* borrowed; false for ignored writes */ void scr_url_set_checked(ScrUrl *u, ScrStr *field, const ScrDyn *value); /* borrowed; conversion may throw */ +/* url.urlToHttpOptions: Node's null-prototype options object for a URL. + * The checked-dynamic form throws ERR_INVALID_ARG_TYPE for a primitive or + * null and has no lowering for an object that is not a URL. Borrowed; +1, + * or NULL with the error pending. */ +ScrDyn *scr_url_to_http_options(ScrUrl *u); +ScrDyn *scr_url_to_http_options_dyn(const ScrDyn *value); /* node:url's legacy surface (scr_url_legacy.c — linked with the regex, * querystring and dyn-async units). url.parse() answers a checked-dynamic * Url instance; format() accepts a Url-shaped object, a string, or a @@ -64,6 +70,9 @@ ScrStr *scr_punycode_to_unicode(const ScrStr *input); ScrArr *scr_punycode_ucs2_decode(const ScrStr *input); ScrStr *scr_url_domain_to_unicode(const ScrDyn *domain, bool missing); ScrStr *scr_url_to_path(ScrUrl *u); /* +1, or throws */ +/* scr_url_to_path as a value: the path string, or the error it would throw + * (+1 dyn, never throws). */ +ScrDyn *scr_url_to_path_value(ScrUrl *u); ScrStr *scr_url_str_to_path(ScrStr *s); /* +1, or throws */ ScrUrl *scr_url_from_path(ScrStr *path); /* +1; throws on win32 UNC malformations only */ ScrUrl *scr_url_from_path_platform(ScrStr *path, bool windows); /* +1; explicit options.windows */ diff --git a/packages/runtime/src/scr_zlib.c b/packages/runtime/src/scr_zlib.c index ff09e7ea1..8756c3d17 100644 --- a/packages/runtime/src/scr_zlib.c +++ b/packages/runtime/src/scr_zlib.c @@ -133,6 +133,11 @@ bool scr_zlib_inflate_exact(const unsigned char *src, size_t src_len, * Modes are Node's node_zlib_mode numbers (DEFLATE 1 ... UNZIP 7). */ struct ScrZlibEngine { z_stream strm; + /* Another codec's engine (scr_zlib_engine_codec): its state answers the + * entries below, which skip the z_stream. */ + const ScrZlibCodec *codec; + void *codec_state; + uint32_t codec_avail_in, codec_avail_out; int mode; int level, window_bits, mem_level, strategy; int flush; @@ -172,6 +177,17 @@ ScrZlibEngine *scr_zlib_engine_new(int mode, int level, int window_bits, int mem return e; } +ScrZlibEngine *scr_zlib_engine_codec(int mode, const ScrZlibCodec *codec, void *state, + bool reject_garbage) { + ScrZlibEngine *e = calloc(1, sizeof *e); + if (!e) scr_zlib_oom(); + e->mode = mode; + e->codec = codec; + e->codec_state = state; + e->reject_garbage = reject_garbage; + return e; +} + static bool scr_zlib_engine_deflating(const ScrZlibEngine *e) { return e->mode == SCR_Z_DEFLATE || e->mode == SCR_Z_GZIP || e->mode == SCR_Z_DEFLATERAW; } @@ -229,6 +245,11 @@ static int scr_zlib_engine_reset_stream(ScrZlibEngine *e) { void scr_zlib_engine_work(ScrZlibEngine *e, int flush, const unsigned char *in, uint32_t in_len, unsigned char *out, uint32_t out_len) { + if (e->codec) { + e->codec->work(e->codec_state, flush, in, in_len, out, out_len, &e->codec_avail_in, + &e->codec_avail_out); + return; + } e->strm.avail_in = in_len; e->strm.next_in = (Bytef *)(uintptr_t)in; e->strm.avail_out = out_len; @@ -286,6 +307,11 @@ void scr_zlib_engine_work(ScrZlibEngine *e, int flush, const unsigned char *in, } void scr_zlib_engine_offsets(const ScrZlibEngine *e, uint32_t *avail_in, uint32_t *avail_out) { + if (e->codec) { + *avail_in = e->codec_avail_in; + *avail_out = e->codec_avail_out; + return; + } *avail_in = e->strm.avail_in; *avail_out = e->strm.avail_out; } @@ -313,6 +339,7 @@ static bool scr_zlib_engine_fail(const ScrZlibEngine *e, const char *message, Sc } bool scr_zlib_engine_error(const ScrZlibEngine *e, ScrZlibError *out) { + if (e->codec) return e->codec->error(e->codec_state, out); switch (e->err) { case Z_OK: case Z_BUF_ERROR: @@ -327,6 +354,7 @@ bool scr_zlib_engine_error(const ScrZlibEngine *e, ScrZlibError *out) { } bool scr_zlib_engine_reset(ScrZlibEngine *e, ScrZlibError *out) { + if (e->codec) return e->codec->reset(e->codec_state, out); switch (scr_zlib_engine_reset_stream(e)) { case 0: return false; case 1: return scr_zlib_engine_fail(e, "Failed to init stream before reset", out); @@ -338,6 +366,7 @@ bool scr_zlib_engine_reset(ScrZlibEngine *e, ScrZlibError *out) { /* SetParams: deflateParams for DEFLATE and DEFLATERAW only (Node's * switch leaves GZIP's level and strategy unchanged). */ bool scr_zlib_engine_params(ScrZlibEngine *e, int level, int strategy, ScrZlibError *out) { + if (e->codec) return false; /* Node's Brotli streams have no params() */ if (scr_zlib_engine_init(e) && e->err != Z_OK) return scr_zlib_engine_fail(e, "Failed to init stream before set parameters", out); e->err = Z_OK; @@ -350,6 +379,11 @@ bool scr_zlib_engine_params(ScrZlibEngine *e, int level, int strategy, ScrZlibEr void scr_zlib_engine_free(ScrZlibEngine *e) { if (!e) return; + if (e->codec) { + e->codec->free(e->codec_state); + free(e); + return; + } if (e->init_done) { if (scr_zlib_engine_deflating(e)) deflateEnd(&e->strm); else inflateEnd(&e->strm); @@ -418,6 +452,15 @@ static bool scr_zlib_is_null(const ScrDyn *v) { void scr_zlib_options_drop(ScrZlibOptions *o) { if (o->dict) scr_bytes_release(o->dict); o->dict = NULL; + if (o->codec_state) o->codec_state_free(o->codec_state); + o->codec_state = NULL; +} + +const ScrZlibBrotliHooks *scr_zlib_brotli_hooks = NULL; + +/* Node's BROTLI_DECODE and BROTLI_ENCODE modes. */ +static bool scr_zlib_brotli_mode(int mode) { + return mode == 8 || mode == 9; } static bool scr_zlib_options_parse_object(int mode, const ScrDyn *opts, ScrZlibOptions *out); @@ -426,6 +469,10 @@ static bool scr_zlib_options_parse_object(int mode, const ScrDyn *opts, ScrZlibO * slot by reference) is read through its materialized view, as a plain * object is. */ bool scr_zlib_options_parse(int mode, const ScrDyn *opts, ScrZlibOptions *out) { + if (scr_zlib_brotli_mode(mode)) { + if (!scr_zlib_brotli_hooks) scr_trap("scriptc: the Brotli codec is not linked\n"); + return scr_zlib_brotli_hooks->options(mode, opts, out); + } if (opts == NULL || opts->kind != SCR_DYN_TYPED_REF) return scr_zlib_options_parse_object(mode, opts, out); ScrDyn *view = scr_dyn_typed_ref_materialize(opts); bool ok = false; @@ -475,6 +522,10 @@ static bool scr_zlib_options_parse_object(int mode, const ScrDyn *opts, ScrZlibO } out->dict = scr_bytes_raw_view(d->v.bytes); } + return scr_zlib_base_options(o, 5, out); +} + +bool scr_zlib_base_options(const ScrDyn *o, double flush_max, ScrZlibOptions *out) { const ScrDyn *rg = scr_zlib_opt(o, "rejectGarbageAfterEnd"); out->reject_garbage = rg != NULL && rg->kind == SCR_DYN_BOOL && rg->v.b; const ScrDyn *cs = scr_zlib_opt(o, "chunkSize"); @@ -488,10 +539,10 @@ static bool scr_zlib_options_parse_object(int mode, const ScrDyn *opts, ScrZlibO } } if (!ok || - !scr_zlib_check_range(scr_zlib_opt(o, "flush"), "options.flush", true, 0, 5, Z_NO_FLUSH, - &out->flush) || - !scr_zlib_check_range(scr_zlib_opt(o, "finishFlush"), "options.finishFlush", true, 0, 5, - Z_FINISH, &out->finish_flush) || + !scr_zlib_check_range(scr_zlib_opt(o, "flush"), "options.flush", true, 0, flush_max, + out->flush, &out->flush) || + !scr_zlib_check_range(scr_zlib_opt(o, "finishFlush"), "options.finishFlush", true, 0, + flush_max, out->finish_flush, &out->finish_flush) || !scr_zlib_check_range(scr_zlib_opt(o, "maxOutputLength"), "options.maxOutputLength", true, 1, 9007199254740991.0, 9007199254740991.0, &out->max_output)) { scr_zlib_options_drop(out); @@ -513,7 +564,8 @@ static bool scr_zlib_options_parse_object(int mode, const ScrDyn *opts, ScrZlibO return true; } -ScrZlibEngine *scr_zlib_engine_from_options(int mode, const ScrZlibOptions *o) { +ScrZlibEngine *scr_zlib_engine_from_options(int mode, ScrZlibOptions *o) { + if (scr_zlib_brotli_mode(mode)) return scr_zlib_brotli_hooks->engine(mode, o); return scr_zlib_engine_new(mode, (int)o->level, (int)o->window_bits, (int)o->mem_level, (int)o->strategy, o->dict ? o->dict->data : NULL, o->dict ? o->dict->len : 0, o->reject_garbage); diff --git a/packages/runtime/src/scr_zlib.h b/packages/runtime/src/scr_zlib.h index 124e157ab..d34b81424 100644 --- a/packages/runtime/src/scr_zlib.h +++ b/packages/runtime/src/scr_zlib.h @@ -42,6 +42,19 @@ bool scr_zlib_engine_error(const ScrZlibEngine *e, ScrZlibError *out); bool scr_zlib_engine_reset(ScrZlibEngine *e, ScrZlibError *out); bool scr_zlib_engine_params(ScrZlibEngine *e, int level, int strategy, ScrZlibError *out); void scr_zlib_engine_free(ScrZlibEngine *e); +/* Another codec behind the same engine (Brotli, scr_brotli.c): the engine + * entries above call these on its state. work runs on a worker thread and + * reports the unused input and output; error and reset fill *out as the + * zlib entries do. free releases the state. */ +typedef struct { + void (*work)(void *state, int flush, const unsigned char *in, uint32_t in_len, unsigned char *out, + uint32_t out_len, uint32_t *avail_in, uint32_t *avail_out); + bool (*error)(const void *state, ScrZlibError *out); + bool (*reset)(void *state, ScrZlibError *out); + void (*free)(void *state); +} ScrZlibCodec; +ScrZlibEngine *scr_zlib_engine_codec(int mode, const ScrZlibCodec *codec, void *state /* moves */, + bool reject_garbage); /* Node's Zlib() and ZlibBase() option ladder, shared by the stream classes * and the one-shot forms with options: false with Node's error pending. * `dict` is a +1 view (or NULL) that scr_zlib_options_drop releases. @@ -52,12 +65,32 @@ typedef struct { ScrBytes *dict; bool reject_garbage, info; double chunk_size, flush, finish_flush, max_output; + /* Another codec's prepared state (a Brotli instance with its parameters + * set), which scr_zlib_engine_from_options moves into the engine and + * scr_zlib_options_drop frees otherwise. */ + void *codec_state; + void (*codec_state_free)(void *state); } ScrZlibOptions; bool scr_zlib_options_parse(int mode, const ScrDyn *opts, ScrZlibOptions *out); void scr_zlib_options_drop(ScrZlibOptions *o); +/* ZlibBase's reads over a truthy options object, after the codec's own: + * chunkSize, flush and finishFlush (within 0..flush_max), maxOutputLength, + * rejectGarbageAfterEnd and info. False with Node's error pending, *out + * dropped. */ +bool scr_zlib_base_options(const ScrDyn *opts, double flush_max, ScrZlibOptions *out); +/* Brotli's option ladder and engine (scr_brotli.c), installed when the + * program uses Brotli: scr_zlib_options_parse and + * scr_zlib_engine_from_options call them for Node's BROTLI_DECODE (8) and + * BROTLI_ENCODE (9) modes. */ +typedef struct { + bool (*options)(int mode, const ScrDyn *opts, ScrZlibOptions *out); + ScrZlibEngine *(*engine)(int mode, ScrZlibOptions *o); +} ScrZlibBrotliHooks; +extern const ScrZlibBrotliHooks *scr_zlib_brotli_hooks; +void scr_brotli_install(void); bool scr_zlib_check_range(const ScrDyn *v, const char *name, bool prop, double lower, double upper, double def, double *out); -ScrZlibEngine *scr_zlib_engine_from_options(int mode, const ScrZlibOptions *o); +ScrZlibEngine *scr_zlib_engine_from_options(int mode, ScrZlibOptions *o); ScrError *scr_zlib_error_new(const ScrZlibError *ze); /* +1 */ /* deflateSync(data, options) and the other one-shot forms with an options * value (undefined for none): Node's processChunkSync over the engine, diff --git a/packages/runtime/src/scr_zlib_stream.c b/packages/runtime/src/scr_zlib_stream.c index e2dcf27f5..8b932a63a 100644 --- a/packages/runtime/src/scr_zlib_stream.c +++ b/packages/runtime/src/scr_zlib_stream.c @@ -433,6 +433,8 @@ static const char *scr_zs_class_name(int mode) { case SCR_ZM_GUNZIP: return "Gunzip"; case SCR_ZM_DEFLATERAW: return "DeflateRaw"; case SCR_ZM_INFLATERAW: return "InflateRaw"; + case 8: return "BrotliDecompress"; + case 9: return "BrotliCompress"; default: return "Unzip"; } } @@ -478,7 +480,8 @@ ScrStream *scr_zlib_stream_new(double mode_d, ScrDyn *opts) { if (!zs->out_buf) scr_zlib_stream_oom(); zs->default_flush = (int)zo.flush; zs->finish_flush = (int)zo.finish_flush; - zs->full_flush = SCR_ZF_FULL; + /* Brotli's full flush is BROTLI_OPERATION_FLUSH (brotliDefaultOpts). */ + zs->full_flush = mode == 8 || mode == 9 ? 1 : SCR_ZF_FULL; zs->level = zo.level; zs->strategy = zo.strategy; zs->reject_garbage = zo.reject_garbage; diff --git a/packages/runtime/test/common-symbols.test.ts b/packages/runtime/test/common-symbols.test.ts index 43d4461e6..344bd01d6 100644 --- a/packages/runtime/test/common-symbols.test.ts +++ b/packages/runtime/test/common-symbols.test.ts @@ -38,6 +38,7 @@ async function commonSymbols(label: string, compiler: string[]): Promise---/` directory — one flavor per driver/target and compiler environment/identity (the lre-objects pattern). Zlib-free binaries never compile any of this; compressed OUTPUT bytes are zlib-version-dependent, which is why the corpus only compares round-trips and fixed-blob inflation. +## brotli/ + +- Project: https://github.com/google/brotli +- Version: 1.2.0 (release tarball brotli-1.2.0.tar.gz, sha256 816c96e8e8f193b40151dad7e8ff37b1221d019dbcb9c35cd3fadbfe6477dfec), the version Node v24.22.0 bundles (`process.versions.brotli`) +- License: MIT (see brotli/LICENSE) + +The codec behind node:zlib's Brotli functions and streams (see packages/runtime/src/scr_brotli.c). Only `c/common`, `c/dec`, `c/enc` and `c/include` are vendored, in upstream's layout (LICENSE beside `c/`); the C++ lazy static initializer (`c/enc/static_init_lazy.cc`), the tools, tests, bindings and build machinery are not. No vendored file is modified, and the files match the copy Node bundles in `deps/brotli`. Because the version is Node's, compressed bytes match Node's for the same parameters, so the corpus compares compressed output as well as round trips. To update, re-fetch the release tarball, copy the same directories, and bump `BROTLI_VERSION` in vendor-inputs.ts. + +The `dec/` and `enc/` directories share file names (`static_init.c`, `state.h`, `prefix.h`), so archive members are named after their directory (`dec-static_init.o`). Brotli-free binaries compile and link none of it. + ## mbedtls/ - Project: https://github.com/Mbed-TLS/mbedtls diff --git a/packages/runtime/vendor/brotli/LICENSE b/packages/runtime/vendor/brotli/LICENSE new file mode 100644 index 000000000..33b7cdd2d --- /dev/null +++ b/packages/runtime/vendor/brotli/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors. + +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/packages/runtime/vendor/brotli/c/common/constants.c b/packages/runtime/vendor/brotli/c/common/constants.c new file mode 100644 index 000000000..ef5a2e2e0 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/constants.c @@ -0,0 +1,15 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "constants.h" + +const BROTLI_MODEL("small") +BrotliPrefixCodeRange _kBrotliPrefixCodeRanges[BROTLI_NUM_BLOCK_LEN_SYMBOLS] = { + {1, 2}, {5, 2}, {9, 2}, {13, 2}, {17, 3}, {25, 3}, + {33, 3}, {41, 3}, {49, 4}, {65, 4}, {81, 4}, {97, 4}, + {113, 5}, {145, 5}, {177, 5}, {209, 5}, {241, 6}, {305, 6}, + {369, 7}, {497, 8}, {753, 9}, {1265, 10}, {2289, 11}, {4337, 12}, + {8433, 13}, {16625, 24}}; diff --git a/packages/runtime/vendor/brotli/c/common/constants.h b/packages/runtime/vendor/brotli/c/common/constants.h new file mode 100644 index 000000000..85e9802c0 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/constants.h @@ -0,0 +1,198 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/** + * @file + * Common constants used in decoder and encoder API. + */ + +#ifndef BROTLI_COMMON_CONSTANTS_H_ +#define BROTLI_COMMON_CONSTANTS_H_ + +#include "platform.h" + +/* Specification: 7.3. Encoding of the context map */ +#define BROTLI_CONTEXT_MAP_MAX_RLE 16 + +/* Specification: 2. Compressed representation overview */ +#define BROTLI_MAX_NUMBER_OF_BLOCK_TYPES 256 + +/* Specification: 3.3. Alphabet sizes: insert-and-copy length */ +#define BROTLI_NUM_LITERAL_SYMBOLS 256 +#define BROTLI_NUM_COMMAND_SYMBOLS 704 +#define BROTLI_NUM_BLOCK_LEN_SYMBOLS 26 +#define BROTLI_MAX_CONTEXT_MAP_SYMBOLS (BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + \ + BROTLI_CONTEXT_MAP_MAX_RLE) +#define BROTLI_MAX_BLOCK_TYPE_SYMBOLS (BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + 2) + +/* Specification: 3.5. Complex prefix codes */ +#define BROTLI_REPEAT_PREVIOUS_CODE_LENGTH 16 +#define BROTLI_REPEAT_ZERO_CODE_LENGTH 17 +#define BROTLI_CODE_LENGTH_CODES (BROTLI_REPEAT_ZERO_CODE_LENGTH + 1) +/* "code length of 8 is repeated" */ +#define BROTLI_INITIAL_REPEATED_CODE_LENGTH 8 + +/* "Large Window Brotli" */ + +/** + * The theoretical maximum number of distance bits specified for large window + * brotli, for 64-bit encoders and decoders. Even when in practice 32-bit + * encoders and decoders only support up to 30 max distance bits, the value is + * set to 62 because it affects the large window brotli file format. + * Specifically, it affects the encoding of simple huffman tree for distances, + * see Specification RFC 7932 chapter 3.4. + */ +#define BROTLI_LARGE_MAX_DISTANCE_BITS 62U +#define BROTLI_LARGE_MIN_WBITS 10 +/** + * The maximum supported large brotli window bits by the encoder and decoder. + * Large window brotli allows up to 62 bits, however the current encoder and + * decoder, designed for 32-bit integers, only support up to 30 bits maximum. + */ +#define BROTLI_LARGE_MAX_WBITS 30 + +/* Specification: 4. Encoding of distances */ +#define BROTLI_NUM_DISTANCE_SHORT_CODES 16 +/** + * Maximal number of "postfix" bits. + * + * Number of "postfix" bits is stored as 2 bits in meta-block header. + */ +#define BROTLI_MAX_NPOSTFIX 3 +#define BROTLI_MAX_NDIRECT 120 +#define BROTLI_MAX_DISTANCE_BITS 24U +#define BROTLI_DISTANCE_ALPHABET_SIZE(NPOSTFIX, NDIRECT, MAXNBITS) ( \ + BROTLI_NUM_DISTANCE_SHORT_CODES + (NDIRECT) + \ + ((MAXNBITS) << ((NPOSTFIX) + 1))) +/* BROTLI_NUM_DISTANCE_SYMBOLS == 1128 */ +#define BROTLI_NUM_DISTANCE_SYMBOLS \ + BROTLI_DISTANCE_ALPHABET_SIZE( \ + BROTLI_MAX_NDIRECT, BROTLI_MAX_NPOSTFIX, BROTLI_LARGE_MAX_DISTANCE_BITS) + +/* ((1 << 26) - 4) is the maximal distance that can be expressed in RFC 7932 + brotli stream using NPOSTFIX = 0 and NDIRECT = 0. With other NPOSTFIX and + NDIRECT values distances up to ((1 << 29) + 88) could be expressed. */ +#define BROTLI_MAX_DISTANCE 0x3FFFFFC + +/* ((1 << 31) - 4) is the safe distance limit. Using this number as a limit + allows safe distance calculation without overflows, given the distance + alphabet size is limited to corresponding size + (see kLargeWindowDistanceCodeLimits). */ +#define BROTLI_MAX_ALLOWED_DISTANCE 0x7FFFFFFC + + +/* Specification: 4. Encoding of Literal Insertion Lengths and Copy Lengths */ +#define BROTLI_NUM_INS_COPY_CODES 24 + +/* 7.1. Context modes and context ID lookup for literals */ +/* "context IDs for literals are in the range of 0..63" */ +#define BROTLI_LITERAL_CONTEXT_BITS 6 + +/* 7.2. Context ID for distances */ +#define BROTLI_DISTANCE_CONTEXT_BITS 2 + +/* 9.1. Format of the Stream Header */ +/* Number of slack bytes for window size. Don't confuse + with BROTLI_NUM_DISTANCE_SHORT_CODES. */ +#define BROTLI_WINDOW_GAP 16 +#define BROTLI_MAX_BACKWARD_LIMIT(W) (((size_t)1 << (W)) - BROTLI_WINDOW_GAP) + +typedef struct BrotliDistanceCodeLimit { + uint32_t max_alphabet_size; + uint32_t max_distance; +} BrotliDistanceCodeLimit; + +/* This function calculates maximal size of distance alphabet, such that the + distances greater than the given values can not be represented. + + This limits are designed to support fast and safe 32-bit decoders. + "32-bit" means that signed integer values up to ((1 << 31) - 1) could be + safely expressed. + + Brotli distance alphabet symbols do not represent consecutive distance + ranges. Each distance alphabet symbol (excluding direct distances and short + codes), represent interleaved (for NPOSTFIX > 0) range of distances. + A "group" of consecutive (1 << NPOSTFIX) symbols represent non-interleaved + range. Two consecutive groups require the same amount of "extra bits". + + It is important that distance alphabet represents complete "groups". + To avoid complex logic on encoder side about interleaved ranges + it was decided to restrict both sides to complete distance code "groups". + */ +BROTLI_UNUSED_FUNCTION BrotliDistanceCodeLimit BrotliCalculateDistanceCodeLimit( + uint32_t max_distance, uint32_t npostfix, uint32_t ndirect) { + BrotliDistanceCodeLimit result; + /* Marking this function as unused, because not all files + including "constants.h" use it -> compiler warns about that. */ + BROTLI_UNUSED(&BrotliCalculateDistanceCodeLimit); + if (max_distance <= ndirect) { + /* This case never happens / exists only for the sake of completeness. */ + result.max_alphabet_size = max_distance + BROTLI_NUM_DISTANCE_SHORT_CODES; + result.max_distance = max_distance; + return result; + } else { + /* The first prohibited value. */ + uint32_t forbidden_distance = max_distance + 1; + /* Subtract "directly" encoded region. */ + uint32_t offset = forbidden_distance - ndirect - 1; + uint32_t ndistbits = 0; + uint32_t tmp; + uint32_t half; + uint32_t group; + /* Postfix for the last dcode in the group. */ + uint32_t postfix = (1u << npostfix) - 1; + uint32_t extra; + uint32_t start; + /* Remove postfix and "head-start". */ + offset = (offset >> npostfix) + 4; + /* Calculate the number of distance bits. */ + tmp = offset / 2; + /* Poor-man's log2floor, to avoid extra dependencies. */ + while (tmp != 0) {ndistbits++; tmp = tmp >> 1;} + /* One bit is covered with subrange addressing ("half"). */ + ndistbits--; + /* Find subrange. */ + half = (offset >> ndistbits) & 1; + /* Calculate the "group" part of dcode. */ + group = ((ndistbits - 1) << 1) | half; + /* Calculated "group" covers the prohibited distance value. */ + if (group == 0) { + /* This case is added for correctness; does not occur for limit > 128. */ + result.max_alphabet_size = ndirect + BROTLI_NUM_DISTANCE_SHORT_CODES; + result.max_distance = ndirect; + return result; + } + /* Decrement "group", so it is the last permitted "group". */ + group--; + /* After group was decremented, ndistbits and half must be recalculated. */ + ndistbits = (group >> 1) + 1; + /* The last available distance in the subrange has all extra bits set. */ + extra = (1u << ndistbits) - 1; + /* Calculate region start. NB: ndistbits >= 1. */ + start = (1u << (ndistbits + 1)) - 4; + /* Move to subregion. */ + start += (group & 1) << ndistbits; + /* Calculate the alphabet size. */ + result.max_alphabet_size = ((group << npostfix) | postfix) + ndirect + + BROTLI_NUM_DISTANCE_SHORT_CODES + 1; + /* Calculate the maximal distance representable by alphabet. */ + result.max_distance = ((start + extra) << npostfix) + postfix + ndirect + 1; + return result; + } +} + +/* Represents the range of values belonging to a prefix code: + [offset, offset + 2^nbits) */ +typedef struct { + uint16_t offset; + uint8_t nbits; +} BrotliPrefixCodeRange; + +/* "Soft-private", it is exported, but not "advertised" as API. */ +BROTLI_COMMON_API extern const BROTLI_MODEL("small") +BrotliPrefixCodeRange _kBrotliPrefixCodeRanges[BROTLI_NUM_BLOCK_LEN_SYMBOLS]; + +#endif /* BROTLI_COMMON_CONSTANTS_H_ */ diff --git a/packages/runtime/vendor/brotli/c/common/context.c b/packages/runtime/vendor/brotli/c/common/context.c new file mode 100644 index 000000000..d3c910cb1 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/context.c @@ -0,0 +1,156 @@ +#include "context.h" + +#include "platform.h" + +/* Common context lookup table for all context modes. */ +const BROTLI_MODEL("small") uint8_t _kBrotliContextLookupTable[2048] = { + /* CONTEXT_LSB6, last byte. */ + 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, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 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, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 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, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 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, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + + /* CONTEXT_LSB6, second last byte, */ + 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, 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, 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, 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, + + /* CONTEXT_MSB6, last byte. */ + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, + 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, + 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, + 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, + 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, + 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, + 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, + 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, + 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, + 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, + 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, + 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, + 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, + + /* CONTEXT_MSB6, second last byte, */ + 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, 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, 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, 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, + + /* CONTEXT_UTF8, last byte. */ + /* ASCII range. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12, + 12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48, + 52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12, + 12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56, + 60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0, + /* UTF8 continuation byte range. */ + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + /* UTF8 lead byte range. */ + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, + + /* CONTEXT_UTF8 second last byte. */ + /* ASCII range. */ + 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0, + /* UTF8 continuation byte range. */ + 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, 0, 0, 0, 0, 0, 0, 0, + /* UTF8 lead byte range. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + + /* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */ + 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56, + + /* CONTEXT_SIGNED, second last byte. */ + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, +}; diff --git a/packages/runtime/vendor/brotli/c/common/context.h b/packages/runtime/vendor/brotli/c/common/context.h new file mode 100644 index 000000000..45b57d8c3 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/context.h @@ -0,0 +1,112 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Lookup table to map the previous two bytes to a context id. + + There are four different context modeling modes defined here: + CONTEXT_LSB6: context id is the least significant 6 bits of the last byte, + CONTEXT_MSB6: context id is the most significant 6 bits of the last byte, + CONTEXT_UTF8: second-order context model tuned for UTF8-encoded text, + CONTEXT_SIGNED: second-order context model tuned for signed integers. + + If |p1| and |p2| are the previous two bytes, and |mode| is current context + mode, we calculate the context as: + + context = ContextLut(mode)[p1] | ContextLut(mode)[p2 + 256]. + + For CONTEXT_UTF8 mode, if the previous two bytes are ASCII characters + (i.e. < 128), this will be equivalent to + + context = 4 * context1(p1) + context2(p2), + + where context1 is based on the previous byte in the following way: + + 0 : non-ASCII control + 1 : \t, \n, \r + 2 : space + 3 : other punctuation + 4 : " ' + 5 : % + 6 : ( < [ { + 7 : ) > ] } + 8 : , ; : + 9 : . + 10 : = + 11 : number + 12 : upper-case vowel + 13 : upper-case consonant + 14 : lower-case vowel + 15 : lower-case consonant + + and context2 is based on the second last byte: + + 0 : control, space + 1 : punctuation + 2 : upper-case letter, number + 3 : lower-case letter + + If the last byte is ASCII, and the second last byte is not (in a valid UTF8 + stream it will be a continuation byte, value between 128 and 191), the + context is the same as if the second last byte was an ASCII control or space. + + If the last byte is a UTF8 lead byte (value >= 192), then the next byte will + be a continuation byte and the context id is 2 or 3 depending on the LSB of + the last byte and to a lesser extent on the second last byte if it is ASCII. + + If the last byte is a UTF8 continuation byte, the second last byte can be: + - continuation byte: the next byte is probably ASCII or lead byte (assuming + 4-byte UTF8 characters are rare) and the context id is 0 or 1. + - lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1 + - lead byte (208 - 255): next byte is continuation byte, context is 2 or 3 + + The possible value combinations of the previous two bytes, the range of + context ids and the type of the next byte is summarized in the table below: + + |--------\-----------------------------------------------------------------| + | \ Last byte | + | Second \---------------------------------------------------------------| + | last byte \ ASCII | cont. byte | lead byte | + | \ (0-127) | (128-191) | (192-) | + |=============|===================|=====================|==================| + | ASCII | next: ASCII/lead | not valid | next: cont. | + | (0-127) | context: 4 - 63 | | context: 2 - 3 | + |-------------|-------------------|---------------------|------------------| + | cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. | + | (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 | + |-------------|-------------------|---------------------|------------------| + | lead byte | not valid | next: ASCII/lead | not valid | + | (192-207) | | context: 0 - 1 | | + |-------------|-------------------|---------------------|------------------| + | lead byte | not valid | next: cont. | not valid | + | (208-) | | context: 2 - 3 | | + |-------------|-------------------|---------------------|------------------| +*/ + +#ifndef BROTLI_COMMON_CONTEXT_H_ +#define BROTLI_COMMON_CONTEXT_H_ + +#include "platform.h" + +typedef enum ContextType { + CONTEXT_LSB6 = 0, + CONTEXT_MSB6 = 1, + CONTEXT_UTF8 = 2, + CONTEXT_SIGNED = 3 +} ContextType; + +/* "Soft-private", it is exported, but not "advertised" as API. */ +/* Common context lookup table for all context modes. */ +BROTLI_COMMON_API extern const uint8_t _kBrotliContextLookupTable[2048]; + +typedef const uint8_t* ContextLut; + +/* typeof(MODE) == ContextType; returns ContextLut */ +#define BROTLI_CONTEXT_LUT(MODE) (&_kBrotliContextLookupTable[(MODE) << 9]) + +/* typeof(LUT) == ContextLut */ +#define BROTLI_CONTEXT(P1, P2, LUT) ((LUT)[P1] | ((LUT) + 256)[P2]) + +#endif /* BROTLI_COMMON_CONTEXT_H_ */ diff --git a/packages/runtime/vendor/brotli/c/common/dictionary.c b/packages/runtime/vendor/brotli/c/common/dictionary.c new file mode 100644 index 000000000..ef43af9bf --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/dictionary.c @@ -0,0 +1,64 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "dictionary.h" +#include "platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if !defined(BROTLI_EXTERNAL_DICTIONARY_DATA) +/* Embed kBrotliDictionaryData */ +#include "dictionary_inc.h" +static const BROTLI_MODEL("small") BrotliDictionary kBrotliDictionary = { +#else +static BROTLI_MODEL("small") BrotliDictionary kBrotliDictionary = { +#endif + /* size_bits_by_length */ + { + 0, 0, 0, 0, 10, 10, 11, 11, + 10, 10, 10, 10, 10, 9, 9, 8, + 7, 7, 8, 7, 7, 6, 6, 5, + 5, 0, 0, 0, 0, 0, 0, 0 + }, + + /* offsets_by_length */ + { + 0, 0, 0, 0, 0, 4096, 9216, 21504, + 35840, 44032, 53248, 63488, 74752, 87040, 93696, 100864, + 104704, 106752, 108928, 113536, 115968, 118528, 119872, 121280, + 122016, 122784, 122784, 122784, 122784, 122784, 122784, 122784 + }, + + /* data_size == sizeof(kBrotliDictionaryData) */ + 122784, + + /* data */ +#if defined(BROTLI_EXTERNAL_DICTIONARY_DATA) + NULL +#else + kBrotliDictionaryData +#endif +}; + +const BrotliDictionary* BrotliGetDictionary(void) { + return &kBrotliDictionary; +} + +void BrotliSetDictionaryData(const uint8_t* data) { +#if defined(BROTLI_EXTERNAL_DICTIONARY_DATA) + if (!!data && !kBrotliDictionary.data) { + kBrotliDictionary.data = data; + } +#else + BROTLI_UNUSED(data); // Appease -Werror=unused-parameter +#endif +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/common/dictionary.h b/packages/runtime/vendor/brotli/c/common/dictionary.h new file mode 100644 index 000000000..ed683b0ae --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/dictionary.h @@ -0,0 +1,63 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Collection of static dictionary words. */ + +#ifndef BROTLI_COMMON_DICTIONARY_H_ +#define BROTLI_COMMON_DICTIONARY_H_ + +#include "platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct BrotliDictionary { + /** + * Number of bits to encode index of dictionary word in a bucket. + * + * Specification: Appendix A. Static Dictionary Data + * + * Words in a dictionary are bucketed by length. + * @c 0 means that there are no words of a given length. + * Dictionary consists of words with length of [4..24] bytes. + * Values at [0..3] and [25..31] indices should not be addressed. + */ + uint8_t size_bits_by_length[32]; + + /* assert(offset[i + 1] == offset[i] + (bits[i] ? (i << bits[i]) : 0)) */ + uint32_t offsets_by_length[32]; + + /* assert(data_size == offsets_by_length[31]) */ + size_t data_size; + + /* Data array is not bound, and should obey to size_bits_by_length values. + Specified size matches default (RFC 7932) dictionary. Its size is + defined by data_size */ + const uint8_t* data; +} BrotliDictionary; + +BROTLI_COMMON_API const BrotliDictionary* BrotliGetDictionary(void); + +/** + * Sets dictionary data. + * + * When dictionary data is already set / present, this method is no-op. + * + * Dictionary data MUST be provided before BrotliGetDictionary is invoked. + * This method is used ONLY in multi-client environment (e.g. C + Java), + * to reduce storage by sharing single dictionary between implementations. + */ +BROTLI_COMMON_API void BrotliSetDictionaryData(const uint8_t* data); + +#define BROTLI_MIN_DICTIONARY_WORD_LENGTH 4 +#define BROTLI_MAX_DICTIONARY_WORD_LENGTH 24 + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_COMMON_DICTIONARY_H_ */ diff --git a/packages/runtime/vendor/brotli/c/common/dictionary_inc.h b/packages/runtime/vendor/brotli/c/common/dictionary_inc.h new file mode 100644 index 000000000..f40a93ecc --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/dictionary_inc.h @@ -0,0 +1,5847 @@ +static const BROTLI_MODEL("small") uint8_t kBrotliDictionaryData[] = { +116,105,109,101,100,111,119,110,108,105,102,101,108,101,102,116,98,97,99,107,99, +111,100,101,100,97,116,97,115,104,111,119,111,110,108,121,115,105,116,101,99,105 +,116,121,111,112,101,110,106,117,115,116,108,105,107,101,102,114,101,101,119,111 +,114,107,116,101,120,116,121,101,97,114,111,118,101,114,98,111,100,121,108,111, +118,101,102,111,114,109,98,111,111,107,112,108,97,121,108,105,118,101,108,105, +110,101,104,101,108,112,104,111,109,101,115,105,100,101,109,111,114,101,119,111, +114,100,108,111,110,103,116,104,101,109,118,105,101,119,102,105,110,100,112,97, +103,101,100,97,121,115,102,117,108,108,104,101,97,100,116,101,114,109,101,97,99, +104,97,114,101,97,102,114,111,109,116,114,117,101,109,97,114,107,97,98,108,101, +117,112,111,110,104,105,103,104,100,97,116,101,108,97,110,100,110,101,119,115, +101,118,101,110,110,101,120,116,99,97,115,101,98,111,116,104,112,111,115,116,117 +,115,101,100,109,97,100,101,104,97,110,100,104,101,114,101,119,104,97,116,110,97 +,109,101,76,105,110,107,98,108,111,103,115,105,122,101,98,97,115,101,104,101,108 +,100,109,97,107,101,109,97,105,110,117,115,101,114,39,41,32,43,104,111,108,100, +101,110,100,115,119,105,116,104,78,101,119,115,114,101,97,100,119,101,114,101, +115,105,103,110,116,97,107,101,104,97,118,101,103,97,109,101,115,101,101,110,99, +97,108,108,112,97,116,104,119,101,108,108,112,108,117,115,109,101,110,117,102, +105,108,109,112,97,114,116,106,111,105,110,116,104,105,115,108,105,115,116,103, +111,111,100,110,101,101,100,119,97,121,115,119,101,115,116,106,111,98,115,109, +105,110,100,97,108,115,111,108,111,103,111,114,105,99,104,117,115,101,115,108,97 +,115,116,116,101,97,109,97,114,109,121,102,111,111,100,107,105,110,103,119,105, +108,108,101,97,115,116,119,97,114,100,98,101,115,116,102,105,114,101,80,97,103, +101,107,110,111,119,97,119,97,121,46,112,110,103,109,111,118,101,116,104,97,110, +108,111,97,100,103,105,118,101,115,101,108,102,110,111,116,101,109,117,99,104, +102,101,101,100,109,97,110,121,114,111,99,107,105,99,111,110,111,110,99,101,108, +111,111,107,104,105,100,101,100,105,101,100,72,111,109,101,114,117,108,101,104, +111,115,116,97,106,97,120,105,110,102,111,99,108,117,98,108,97,119,115,108,101, +115,115,104,97,108,102,115,111,109,101,115,117,99,104,122,111,110,101,49,48,48, +37,111,110,101,115,99,97,114,101,84,105,109,101,114,97,99,101,98,108,117,101,102 +,111,117,114,119,101,101,107,102,97,99,101,104,111,112,101,103,97,118,101,104,97 +,114,100,108,111,115,116,119,104,101,110,112,97,114,107,107,101,112,116,112,97, +115,115,115,104,105,112,114,111,111,109,72,84,77,76,112,108,97,110,84,121,112, +101,100,111,110,101,115,97,118,101,107,101,101,112,102,108,97,103,108,105,110, +107,115,111,108,100,102,105,118,101,116,111,111,107,114,97,116,101,116,111,119, +110,106,117,109,112,116,104,117,115,100,97,114,107,99,97,114,100,102,105,108,101 +,102,101,97,114,115,116,97,121,107,105,108,108,116,104,97,116,102,97,108,108,97, +117,116,111,101,118,101,114,46,99,111,109,116,97,108,107,115,104,111,112,118,111 +,116,101,100,101,101,112,109,111,100,101,114,101,115,116,116,117,114,110,98,111, +114,110,98,97,110,100,102,101,108,108,114,111,115,101,117,114,108,40,115,107,105 +,110,114,111,108,101,99,111,109,101,97,99,116,115,97,103,101,115,109,101,101,116 +,103,111,108,100,46,106,112,103,105,116,101,109,118,97,114,121,102,101,108,116, +116,104,101,110,115,101,110,100,100,114,111,112,86,105,101,119,99,111,112,121,49 +,46,48,34,60,47,97,62,115,116,111,112,101,108,115,101,108,105,101,115,116,111, +117,114,112,97,99,107,46,103,105,102,112,97,115,116,99,115,115,63,103,114,97,121 +,109,101,97,110,38,103,116,59,114,105,100,101,115,104,111,116,108,97,116,101,115 +,97,105,100,114,111,97,100,118,97,114,32,102,101,101,108,106,111,104,110,114,105 +,99,107,112,111,114,116,102,97,115,116,39,85,65,45,100,101,97,100,60,47,98,62, +112,111,111,114,98,105,108,108,116,121,112,101,85,46,83,46,119,111,111,100,109, +117,115,116,50,112,120,59,73,110,102,111,114,97,110,107,119,105,100,101,119,97, +110,116,119,97,108,108,108,101,97,100,91,48,93,59,112,97,117,108,119,97,118,101, +115,117,114,101,36,40,39,35,119,97,105,116,109,97,115,115,97,114,109,115,103,111 +,101,115,103,97,105,110,108,97,110,103,112,97,105,100,33,45,45,32,108,111,99,107 +,117,110,105,116,114,111,111,116,119,97,108,107,102,105,114,109,119,105,102,101, +120,109,108,34,115,111,110,103,116,101,115,116,50,48,112,120,107,105,110,100,114 +,111,119,115,116,111,111,108,102,111,110,116,109,97,105,108,115,97,102,101,115, +116,97,114,109,97,112,115,99,111,114,101,114,97,105,110,102,108,111,119,98,97,98 +,121,115,112,97,110,115,97,121,115,52,112,120,59,54,112,120,59,97,114,116,115, +102,111,111,116,114,101,97,108,119,105,107,105,104,101,97,116,115,116,101,112, +116,114,105,112,111,114,103,47,108,97,107,101,119,101,97,107,116,111,108,100,70, +111,114,109,99,97,115,116,102,97,110,115,98,97,110,107,118,101,114,121,114,117, +110,115,106,117,108,121,116,97,115,107,49,112,120,59,103,111,97,108,103,114,101, +119,115,108,111,119,101,100,103,101,105,100,61,34,115,101,116,115,53,112,120,59, +46,106,115,63,52,48,112,120,105,102,32,40,115,111,111,110,115,101,97,116,110,111 +,110,101,116,117,98,101,122,101,114,111,115,101,110,116,114,101,101,100,102,97, +99,116,105,110,116,111,103,105,102,116,104,97,114,109,49,56,112,120,99,97,109, +101,104,105,108,108,98,111,108,100,122,111,111,109,118,111,105,100,101,97,115, +121,114,105,110,103,102,105,108,108,112,101,97,107,105,110,105,116,99,111,115, +116,51,112,120,59,106,97,99,107,116,97,103,115,98,105,116,115,114,111,108,108, +101,100,105,116,107,110,101,119,110,101,97,114,60,33,45,45,103,114,111,119,74,83 +,79,78,100,117,116,121,78,97,109,101,115,97,108,101,121,111,117,32,108,111,116, +115,112,97,105,110,106,97,122,122,99,111,108,100,101,121,101,115,102,105,115,104 +,119,119,119,46,114,105,115,107,116,97,98,115,112,114,101,118,49,48,112,120,114, +105,115,101,50,53,112,120,66,108,117,101,100,105,110,103,51,48,48,44,98,97,108, +108,102,111,114,100,101,97,114,110,119,105,108,100,98,111,120,46,102,97,105,114, +108,97,99,107,118,101,114,115,112,97,105,114,106,117,110,101,116,101,99,104,105, +102,40,33,112,105,99,107,101,118,105,108,36,40,34,35,119,97,114,109,108,111,114, +100,100,111,101,115,112,117,108,108,44,48,48,48,105,100,101,97,100,114,97,119, +104,117,103,101,115,112,111,116,102,117,110,100,98,117,114,110,104,114,101,102, +99,101,108,108,107,101,121,115,116,105,99,107,104,111,117,114,108,111,115,115, +102,117,101,108,49,50,112,120,115,117,105,116,100,101,97,108,82,83,83,34,97,103, +101,100,103,114,101,121,71,69,84,34,101,97,115,101,97,105,109,115,103,105,114, +108,97,105,100,115,56,112,120,59,110,97,118,121,103,114,105,100,116,105,112,115, +35,57,57,57,119,97,114,115,108,97,100,121,99,97,114,115,41,59,32,125,112,104,112 +,63,104,101,108,108,116,97,108,108,119,104,111,109,122,104,58,229,42,47,13,10,32 +,49,48,48,104,97,108,108,46,10,10,65,55,112,120,59,112,117,115,104,99,104,97,116 +,48,112,120,59,99,114,101,119,42,47,60,47,104,97,115,104,55,53,112,120,102,108, +97,116,114,97,114,101,32,38,38,32,116,101,108,108,99,97,109,112,111,110,116,111, +108,97,105,100,109,105,115,115,115,107,105,112,116,101,110,116,102,105,110,101, +109,97,108,101,103,101,116,115,112,108,111,116,52,48,48,44,13,10,13,10,99,111, +111,108,102,101,101,116,46,112,104,112,60,98,114,62,101,114,105,99,109,111,115, +116,103,117,105,100,98,101,108,108,100,101,115,99,104,97,105,114,109,97,116,104, +97,116,111,109,47,105,109,103,38,35,56,50,108,117,99,107,99,101,110,116,48,48,48 +,59,116,105,110,121,103,111,110,101,104,116,109,108,115,101,108,108,100,114,117, +103,70,82,69,69,110,111,100,101,110,105,99,107,63,105,100,61,108,111,115,101,110 +,117,108,108,118,97,115,116,119,105,110,100,82,83,83,32,119,101,97,114,114,101, +108,121,98,101,101,110,115,97,109,101,100,117,107,101,110,97,115,97,99,97,112, +101,119,105,115,104,103,117,108,102,84,50,51,58,104,105,116,115,115,108,111,116, +103,97,116,101,107,105,99,107,98,108,117,114,116,104,101,121,49,53,112,120,39,39 +,41,59,41,59,34,62,109,115,105,101,119,105,110,115,98,105,114,100,115,111,114, +116,98,101,116,97,115,101,101,107,84,49,56,58,111,114,100,115,116,114,101,101, +109,97,108,108,54,48,112,120,102,97,114,109,226,128,153,115,98,111,121,115,91,48 +,93,46,39,41,59,34,80,79,83,84,98,101,97,114,107,105,100,115,41,59,125,125,109, +97,114,121,116,101,110,100,40,85,75,41,113,117,97,100,122,104,58,230,45,115,105, +122,45,45,45,45,112,114,111,112,39,41,59,13,108,105,102,116,84,49,57,58,118,105, +99,101,97,110,100,121,100,101,98,116,62,82,83,83,112,111,111,108,110,101,99,107, +98,108,111,119,84,49,54,58,100,111,111,114,101,118,97,108,84,49,55,58,108,101, +116,115,102,97,105,108,111,114,97,108,112,111,108,108,110,111,118,97,99,111,108, +115,103,101,110,101,32,226,128,148,115,111,102,116,114,111,109,101,116,105,108, +108,114,111,115,115,60,104,51,62,112,111,117,114,102,97,100,101,112,105,110,107, +60,116,114,62,109,105,110,105,41,124,33,40,109,105,110,101,122,104,58,232,98,97, +114,115,104,101,97,114,48,48,41,59,109,105,108,107,32,45,45,62,105,114,111,110, +102,114,101,100,100,105,115,107,119,101,110,116,115,111,105,108,112,117,116,115, +47,106,115,47,104,111,108,121,84,50,50,58,73,83,66,78,84,50,48,58,97,100,97,109, +115,101,101,115,60,104,50,62,106,115,111,110,39,44,32,39,99,111,110,116,84,50,49 +,58,32,82,83,83,108,111,111,112,97,115,105,97,109,111,111,110,60,47,112,62,115, +111,117,108,76,73,78,69,102,111,114,116,99,97,114,116,84,49,52,58,60,104,49,62, +56,48,112,120,33,45,45,60,57,112,120,59,84,48,52,58,109,105,107,101,58,52,54,90, +110,105,99,101,105,110,99,104,89,111,114,107,114,105,99,101,122,104,58,228,39,41 +,41,59,112,117,114,101,109,97,103,101,112,97,114,97,116,111,110,101,98,111,110, +100,58,51,55,90,95,111,102,95,39,93,41,59,48,48,48,44,122,104,58,231,116,97,110, +107,121,97,114,100,98,111,119,108,98,117,115,104,58,53,54,90,74,97,118,97,51,48, +112,120,10,124,125,10,37,67,51,37,58,51,52,90,106,101,102,102,69,88,80,73,99,97, +115,104,118,105,115,97,103,111,108,102,115,110,111,119,122,104,58,233,113,117, +101,114,46,99,115,115,115,105,99,107,109,101,97,116,109,105,110,46,98,105,110, +100,100,101,108,108,104,105,114,101,112,105,99,115,114,101,110,116,58,51,54,90, +72,84,84,80,45,50,48,49,102,111,116,111,119,111,108,102,69,78,68,32,120,98,111, +120,58,53,52,90,66,79,68,89,100,105,99,107,59,10,125,10,101,120,105,116,58,51,53 +,90,118,97,114,115,98,101,97,116,39,125,41,59,100,105,101,116,57,57,57,59,97,110 +,110,101,125,125,60,47,91,105,93,46,76,97,110,103,107,109,194,178,119,105,114, +101,116,111,121,115,97,100,100,115,115,101,97,108,97,108,101,120,59,10,9,125,101 +,99,104,111,110,105,110,101,46,111,114,103,48,48,53,41,116,111,110,121,106,101, +119,115,115,97,110,100,108,101,103,115,114,111,111,102,48,48,48,41,32,50,48,48, +119,105,110,101,103,101,97,114,100,111,103,115,98,111,111,116,103,97,114,121,99, +117,116,115,116,121,108,101,116,101,109,112,116,105,111,110,46,120,109,108,99, +111,99,107,103,97,110,103,36,40,39,46,53,48,112,120,80,104,46,68,109,105,115,99, +97,108,97,110,108,111,97,110,100,101,115,107,109,105,108,101,114,121,97,110,117, +110,105,120,100,105,115,99,41,59,125,10,100,117,115,116,99,108,105,112,41,46,10, +10,55,48,112,120,45,50,48,48,68,86,68,115,55,93,62,60,116,97,112,101,100,101,109 +,111,105,43,43,41,119,97,103,101,101,117,114,111,112,104,105,108,111,112,116,115 +,104,111,108,101,70,65,81,115,97,115,105,110,45,50,54,84,108,97,98,115,112,101, +116,115,85,82,76,32,98,117,108,107,99,111,111,107,59,125,13,10,72,69,65,68,91,48 +,93,41,97,98,98,114,106,117,97,110,40,49,57,56,108,101,115,104,116,119,105,110, +60,47,105,62,115,111,110,121,103,117,121,115,102,117,99,107,112,105,112,101,124, +45,10,33,48,48,50,41,110,100,111,119,91,49,93,59,91,93,59,10,76,111,103,32,115, +97,108,116,13,10,9,9,98,97,110,103,116,114,105,109,98,97,116,104,41,123,13,10,48 +,48,112,120,10,125,41,59,107,111,58,236,102,101,101,115,97,100,62,13,115,58,47, +47,32,91,93,59,116,111,108,108,112,108,117,103,40,41,123,10,123,13,10,32,46,106, +115,39,50,48,48,112,100,117,97,108,98,111,97,116,46,74,80,71,41,59,10,125,113, +117,111,116,41,59,10,10,39,41,59,10,13,10,125,13,50,48,49,52,50,48,49,53,50,48, +49,54,50,48,49,55,50,48,49,56,50,48,49,57,50,48,50,48,50,48,50,49,50,48,50,50,50 +,48,50,51,50,48,50,52,50,48,50,53,50,48,50,54,50,48,50,55,50,48,50,56,50,48,50, +57,50,48,51,48,50,48,51,49,50,48,51,50,50,48,51,51,50,48,51,52,50,48,51,53,50,48 +,51,54,50,48,51,55,50,48,49,51,50,48,49,50,50,48,49,49,50,48,49,48,50,48,48,57, +50,48,48,56,50,48,48,55,50,48,48,54,50,48,48,53,50,48,48,52,50,48,48,51,50,48,48 +,50,50,48,48,49,50,48,48,48,49,57,57,57,49,57,57,56,49,57,57,55,49,57,57,54,49, +57,57,53,49,57,57,52,49,57,57,51,49,57,57,50,49,57,57,49,49,57,57,48,49,57,56,57 +,49,57,56,56,49,57,56,55,49,57,56,54,49,57,56,53,49,57,56,52,49,57,56,51,49,57, +56,50,49,57,56,49,49,57,56,48,49,57,55,57,49,57,55,56,49,57,55,55,49,57,55,54,49 +,57,55,53,49,57,55,52,49,57,55,51,49,57,55,50,49,57,55,49,49,57,55,48,49,57,54, +57,49,57,54,56,49,57,54,55,49,57,54,54,49,57,54,53,49,57,54,52,49,57,54,51,49,57 +,54,50,49,57,54,49,49,57,54,48,49,57,53,57,49,57,53,56,49,57,53,55,49,57,53,54, +49,57,53,53,49,57,53,52,49,57,53,51,49,57,53,50,49,57,53,49,49,57,53,48,49,48,48 +,48,49,48,50,52,49,51,57,52,48,48,48,48,57,57,57,57,99,111,109,111,109,195,161, +115,101,115,116,101,101,115,116,97,112,101,114,111,116,111,100,111,104,97,99,101 +,99,97,100,97,97,195,177,111,98,105,101,110,100,195,173,97,97,115,195,173,118, +105,100,97,99,97,115,111,111,116,114,111,102,111,114,111,115,111,108,111,111,116 +,114,97,99,117,97,108,100,105,106,111,115,105,100,111,103,114,97,110,116,105,112 +,111,116,101,109,97,100,101,98,101,97,108,103,111,113,117,195,169,101,115,116, +111,110,97,100,97,116,114,101,115,112,111,99,111,99,97,115,97,98,97,106,111,116, +111,100,97,115,105,110,111,97,103,117,97,112,117,101,115,117,110,111,115,97,110, +116,101,100,105,99,101,108,117,105,115,101,108,108,97,109,97,121,111,122,111,110 +,97,97,109,111,114,112,105,115,111,111,98,114,97,99,108,105,99,101,108,108,111, +100,105,111,115,104,111,114,97,99,97,115,105,208,183,208,176,208,189,208,176,208 +,190,208,188,209,128,208,176,209,128,209,131,209,130,208,176,208,189,208,181,208 +,191,208,190,208,190,209,130,208,184,208,183,208,189,208,190,208,180,208,190,209 +,130,208,190,208,182,208,181,208,190,208,189,208,184,209,133,208,157,208,176,208 +,181,208,181,208,177,209,139,208,188,209,139,208,146,209,139,209,129,208,190,208 +,178,209,139,208,178,208,190,208,157,208,190,208,190,208,177,208,159,208,190,208 +,187,208,184,208,189,208,184,208,160,208,164,208,157,208,181,208,156,209,139,209 +,130,209,139,208,158,208,189,208,184,208,188,208,180,208,176,208,151,208,176,208 +,148,208,176,208,157,209,131,208,158,208,177,209,130,208,181,208,152,208,183,208 +,181,208,185,208,189,209,131,208,188,208,188,208,162,209,139,209,131,208,182,217 +,129,217,138,216,163,217,134,217,133,216,167,217,133,216,185,217,131,217,132,216 +,163,217,136,216,177,216,175,217,138,216,167,217,129,217,137,217,135,217,136,217 +,132,217,133,217,132,217,131,216,167,217,136,217,132,217,135,216,168,216,179,216 +,167,217,132,216,165,217,134,217,135,217,138,216,163,217,138,217,130,216,175,217 +,135,217,132,216,171,217,133,216,168,217,135,217,132,217,136,217,132,217,138,216 +,168,217,132,216,167,217,138,216,168,217,131,216,180,217,138,216,167,217,133,216 +,163,217,133,217,134,216,170,216,168,217,138,217,132,217,134,216,173,216,168,217 +,135,217,133,217,133,216,180,217,136,216,180,102,105,114,115,116,118,105,100,101 +,111,108,105,103,104,116,119,111,114,108,100,109,101,100,105,97,119,104,105,116, +101,99,108,111,115,101,98,108,97,99,107,114,105,103,104,116,115,109,97,108,108, +98,111,111,107,115,112,108,97,99,101,109,117,115,105,99,102,105,101,108,100,111, +114,100,101,114,112,111,105,110,116,118,97,108,117,101,108,101,118,101,108,116, +97,98,108,101,98,111,97,114,100,104,111,117,115,101,103,114,111,117,112,119,111, +114,107,115,121,101,97,114,115,115,116,97,116,101,116,111,100,97,121,119,97,116, +101,114,115,116,97,114,116,115,116,121,108,101,100,101,97,116,104,112,111,119, +101,114,112,104,111,110,101,110,105,103,104,116,101,114,114,111,114,105,110,112, +117,116,97,98,111,117,116,116,101,114,109,115,116,105,116,108,101,116,111,111, +108,115,101,118,101,110,116,108,111,99,97,108,116,105,109,101,115,108,97,114,103 +,101,119,111,114,100,115,103,97,109,101,115,115,104,111,114,116,115,112,97,99, +101,102,111,99,117,115,99,108,101,97,114,109,111,100,101,108,98,108,111,99,107, +103,117,105,100,101,114,97,100,105,111,115,104,97,114,101,119,111,109,101,110,97 +,103,97,105,110,109,111,110,101,121,105,109,97,103,101,110,97,109,101,115,121, +111,117,110,103,108,105,110,101,115,108,97,116,101,114,99,111,108,111,114,103, +114,101,101,110,102,114,111,110,116,38,97,109,112,59,119,97,116,99,104,102,111, +114,99,101,112,114,105,99,101,114,117,108,101,115,98,101,103,105,110,97,102,116, +101,114,118,105,115,105,116,105,115,115,117,101,97,114,101,97,115,98,101,108,111 +,119,105,110,100,101,120,116,111,116,97,108,104,111,117,114,115,108,97,98,101, +108,112,114,105,110,116,112,114,101,115,115,98,117,105,108,116,108,105,110,107, +115,115,112,101,101,100,115,116,117,100,121,116,114,97,100,101,102,111,117,110, +100,115,101,110,115,101,117,110,100,101,114,115,104,111,119,110,102,111,114,109, +115,114,97,110,103,101,97,100,100,101,100,115,116,105,108,108,109,111,118,101, +100,116,97,107,101,110,97,98,111,118,101,102,108,97,115,104,102,105,120,101,100, +111,102,116,101,110,111,116,104,101,114,118,105,101,119,115,99,104,101,99,107, +108,101,103,97,108,114,105,118,101,114,105,116,101,109,115,113,117,105,99,107, +115,104,97,112,101,104,117,109,97,110,101,120,105,115,116,103,111,105,110,103, +109,111,118,105,101,116,104,105,114,100,98,97,115,105,99,112,101,97,99,101,115, +116,97,103,101,119,105,100,116,104,108,111,103,105,110,105,100,101,97,115,119, +114,111,116,101,112,97,103,101,115,117,115,101,114,115,100,114,105,118,101,115, +116,111,114,101,98,114,101,97,107,115,111,117,116,104,118,111,105,99,101,115,105 +,116,101,115,109,111,110,116,104,119,104,101,114,101,98,117,105,108,100,119,104, +105,99,104,101,97,114,116,104,102,111,114,117,109,116,104,114,101,101,115,112, +111,114,116,112,97,114,116,121,67,108,105,99,107,108,111,119,101,114,108,105,118 +,101,115,99,108,97,115,115,108,97,121,101,114,101,110,116,114,121,115,116,111, +114,121,117,115,97,103,101,115,111,117,110,100,99,111,117,114,116,121,111,117, +114,32,98,105,114,116,104,112,111,112,117,112,116,121,112,101,115,97,112,112,108 +,121,73,109,97,103,101,98,101,105,110,103,117,112,112,101,114,110,111,116,101, +115,101,118,101,114,121,115,104,111,119,115,109,101,97,110,115,101,120,116,114, +97,109,97,116,99,104,116,114,97,99,107,107,110,111,119,110,101,97,114,108,121,98 +,101,103,97,110,115,117,112,101,114,112,97,112,101,114,110,111,114,116,104,108, +101,97,114,110,103,105,118,101,110,110,97,109,101,100,101,110,100,101,100,84,101 +,114,109,115,112,97,114,116,115,71,114,111,117,112,98,114,97,110,100,117,115,105 +,110,103,119,111,109,97,110,102,97,108,115,101,114,101,97,100,121,97,117,100,105 +,111,116,97,107,101,115,119,104,105,108,101,46,99,111,109,47,108,105,118,101,100 +,99,97,115,101,115,100,97,105,108,121,99,104,105,108,100,103,114,101,97,116,106, +117,100,103,101,116,104,111,115,101,117,110,105,116,115,110,101,118,101,114,98, +114,111,97,100,99,111,97,115,116,99,111,118,101,114,97,112,112,108,101,102,105, +108,101,115,99,121,99,108,101,115,99,101,110,101,112,108,97,110,115,99,108,105, +99,107,119,114,105,116,101,113,117,101,101,110,112,105,101,99,101,101,109,97,105 +,108,102,114,97,109,101,111,108,100,101,114,112,104,111,116,111,108,105,109,105, +116,99,97,99,104,101,99,105,118,105,108,115,99,97,108,101,101,110,116,101,114, +116,104,101,109,101,116,104,101,114,101,116,111,117,99,104,98,111,117,110,100, +114,111,121,97,108,97,115,107,101,100,119,104,111,108,101,115,105,110,99,101,115 +,116,111,99,107,32,110,97,109,101,102,97,105,116,104,104,101,97,114,116,101,109, +112,116,121,111,102,102,101,114,115,99,111,112,101,111,119,110,101,100,109,105, +103,104,116,97,108,98,117,109,116,104,105,110,107,98,108,111,111,100,97,114,114, +97,121,109,97,106,111,114,116,114,117,115,116,99,97,110,111,110,117,110,105,111, +110,99,111,117,110,116,118,97,108,105,100,115,116,111,110,101,83,116,121,108,101 +,76,111,103,105,110,104,97,112,112,121,111,99,99,117,114,108,101,102,116,58,102, +114,101,115,104,113,117,105,116,101,102,105,108,109,115,103,114,97,100,101,110, +101,101,100,115,117,114,98,97,110,102,105,103,104,116,98,97,115,105,115,104,111, +118,101,114,97,117,116,111,59,114,111,117,116,101,46,104,116,109,108,109,105,120 +,101,100,102,105,110,97,108,89,111,117,114,32,115,108,105,100,101,116,111,112, +105,99,98,114,111,119,110,97,108,111,110,101,100,114,97,119,110,115,112,108,105, +116,114,101,97,99,104,82,105,103,104,116,100,97,116,101,115,109,97,114,99,104, +113,117,111,116,101,103,111,111,100,115,76,105,110,107,115,100,111,117,98,116,97 +,115,121,110,99,116,104,117,109,98,97,108,108,111,119,99,104,105,101,102,121,111 +,117,116,104,110,111,118,101,108,49,48,112,120,59,115,101,114,118,101,117,110, +116,105,108,104,97,110,100,115,67,104,101,99,107,83,112,97,99,101,113,117,101, +114,121,106,97,109,101,115,101,113,117,97,108,116,119,105,99,101,48,44,48,48,48, +83,116,97,114,116,112,97,110,101,108,115,111,110,103,115,114,111,117,110,100,101 +,105,103,104,116,115,104,105,102,116,119,111,114,116,104,112,111,115,116,115,108 +,101,97,100,115,119,101,101,107,115,97,118,111,105,100,116,104,101,115,101,109, +105,108,101,115,112,108,97,110,101,115,109,97,114,116,97,108,112,104,97,112,108, +97,110,116,109,97,114,107,115,114,97,116,101,115,112,108,97,121,115,99,108,97, +105,109,115,97,108,101,115,116,101,120,116,115,115,116,97,114,115,119,114,111, +110,103,60,47,104,51,62,116,104,105,110,103,46,111,114,103,47,109,117,108,116, +105,104,101,97,114,100,80,111,119,101,114,115,116,97,110,100,116,111,107,101,110 +,115,111,108,105,100,40,116,104,105,115,98,114,105,110,103,115,104,105,112,115, +115,116,97,102,102,116,114,105,101,100,99,97,108,108,115,102,117,108,108,121,102 +,97,99,116,115,97,103,101,110,116,84,104,105,115,32,47,47,45,45,62,97,100,109, +105,110,101,103,121,112,116,69,118,101,110,116,49,53,112,120,59,69,109,97,105, +108,116,114,117,101,34,99,114,111,115,115,115,112,101,110,116,98,108,111,103,115 +,98,111,120,34,62,110,111,116,101,100,108,101,97,118,101,99,104,105,110,97,115, +105,122,101,115,103,117,101,115,116,60,47,104,52,62,114,111,98,111,116,104,101, +97,118,121,116,114,117,101,44,115,101,118,101,110,103,114,97,110,100,99,114,105, +109,101,115,105,103,110,115,97,119,97,114,101,100,97,110,99,101,112,104,97,115, +101,62,60,33,45,45,101,110,95,85,83,38,35,51,57,59,50,48,48,112,120,95,110,97, +109,101,108,97,116,105,110,101,110,106,111,121,97,106,97,120,46,97,116,105,111, +110,115,109,105,116,104,85,46,83,46,32,104,111,108,100,115,112,101,116,101,114, +105,110,100,105,97,110,97,118,34,62,99,104,97,105,110,115,99,111,114,101,99,111, +109,101,115,100,111,105,110,103,112,114,105,111,114,83,104,97,114,101,49,57,57, +48,115,114,111,109,97,110,108,105,115,116,115,106,97,112,97,110,102,97,108,108, +115,116,114,105,97,108,111,119,110,101,114,97,103,114,101,101,60,47,104,50,62,97 +,98,117,115,101,97,108,101,114,116,111,112,101,114,97,34,45,47,47,87,99,97,114, +100,115,104,105,108,108,115,116,101,97,109,115,80,104,111,116,111,116,114,117, +116,104,99,108,101,97,110,46,112,104,112,63,115,97,105,110,116,109,101,116,97, +108,108,111,117,105,115,109,101,97,110,116,112,114,111,111,102,98,114,105,101, +102,114,111,119,34,62,103,101,110,114,101,116,114,117,99,107,108,111,111,107,115 +,86,97,108,117,101,70,114,97,109,101,46,110,101,116,47,45,45,62,10,60,116,114, +121,32,123,10,118,97,114,32,109,97,107,101,115,99,111,115,116,115,112,108,97,105 +,110,97,100,117,108,116,113,117,101,115,116,116,114,97,105,110,108,97,98,111,114 +,104,101,108,112,115,99,97,117,115,101,109,97,103,105,99,109,111,116,111,114,116 +,104,101,105,114,50,53,48,112,120,108,101,97,115,116,115,116,101,112,115,67,111, +117,110,116,99,111,117,108,100,103,108,97,115,115,115,105,100,101,115,102,117, +110,100,115,104,111,116,101,108,97,119,97,114,100,109,111,117,116,104,109,111, +118,101,115,112,97,114,105,115,103,105,118,101,115,100,117,116,99,104,116,101, +120,97,115,102,114,117,105,116,110,117,108,108,44,124,124,91,93,59,116,111,112, +34,62,10,60,33,45,45,80,79,83,84,34,111,99,101,97,110,60,98,114,47,62,102,108, +111,111,114,115,112,101,97,107,100,101,112,116,104,32,115,105,122,101,98,97,110, +107,115,99,97,116,99,104,99,104,97,114,116,50,48,112,120,59,97,108,105,103,110, +100,101,97,108,115,119,111,117,108,100,53,48,112,120,59,117,114,108,61,34,112,97 +,114,107,115,109,111,117,115,101,77,111,115,116,32,46,46,46,60,47,97,109,111,110 +,103,98,114,97,105,110,98,111,100,121,32,110,111,110,101,59,98,97,115,101,100,99 +,97,114,114,121,100,114,97,102,116,114,101,102,101,114,112,97,103,101,95,104,111 +,109,101,46,109,101,116,101,114,100,101,108,97,121,100,114,101,97,109,112,114, +111,118,101,106,111,105,110,116,60,47,116,114,62,100,114,117,103,115,60,33,45,45 +,32,97,112,114,105,108,105,100,101,97,108,97,108,108,101,110,101,120,97,99,116, +102,111,114,116,104,99,111,100,101,115,108,111,103,105,99,86,105,101,119,32,115, +101,101,109,115,98,108,97,110,107,112,111,114,116,115,32,40,50,48,48,115,97,118, +101,100,95,108,105,110,107,103,111,97,108,115,103,114,97,110,116,103,114,101,101 +,107,104,111,109,101,115,114,105,110,103,115,114,97,116,101,100,51,48,112,120,59 +,119,104,111,115,101,112,97,114,115,101,40,41,59,34,32,66,108,111,99,107,108,105 +,110,117,120,106,111,110,101,115,112,105,120,101,108,39,41,59,34,62,41,59,105, +102,40,45,108,101,102,116,100,97,118,105,100,104,111,114,115,101,70,111,99,117, +115,114,97,105,115,101,98,111,120,101,115,84,114,97,99,107,101,109,101,110,116, +60,47,101,109,62,98,97,114,34,62,46,115,114,99,61,116,111,119,101,114,97,108,116 +,61,34,99,97,98,108,101,104,101,110,114,121,50,52,112,120,59,115,101,116,117,112 +,105,116,97,108,121,115,104,97,114,112,109,105,110,111,114,116,97,115,116,101, +119,97,110,116,115,116,104,105,115,46,114,101,115,101,116,119,104,101,101,108, +103,105,114,108,115,47,99,115,115,47,49,48,48,37,59,99,108,117,98,115,115,116, +117,102,102,98,105,98,108,101,118,111,116,101,115,32,49,48,48,48,107,111,114,101 +,97,125,41,59,13,10,98,97,110,100,115,113,117,101,117,101,61,32,123,125,59,56,48 +,112,120,59,99,107,105,110,103,123,13,10,9,9,97,104,101,97,100,99,108,111,99,107 +,105,114,105,115,104,108,105,107,101,32,114,97,116,105,111,115,116,97,116,115,70 +,111,114,109,34,121,97,104,111,111,41,91,48,93,59,65,98,111,117,116,102,105,110, +100,115,60,47,104,49,62,100,101,98,117,103,116,97,115,107,115,85,82,76,32,61,99, +101,108,108,115,125,41,40,41,59,49,50,112,120,59,112,114,105,109,101,116,101,108 +,108,115,116,117,114,110,115,48,120,54,48,48,46,106,112,103,34,115,112,97,105, +110,98,101,97,99,104,116,97,120,101,115,109,105,99,114,111,97,110,103,101,108,45 +,45,62,60,47,103,105,102,116,115,115,116,101,118,101,45,108,105,110,107,98,111, +100,121,46,125,41,59,10,9,109,111,117,110,116,32,40,49,57,57,70,65,81,60,47,114, +111,103,101,114,102,114,97,110,107,67,108,97,115,115,50,56,112,120,59,102,101, +101,100,115,60,104,49,62,60,115,99,111,116,116,116,101,115,116,115,50,50,112,120 +,59,100,114,105,110,107,41,32,124,124,32,108,101,119,105,115,115,104,97,108,108, +35,48,51,57,59,32,102,111,114,32,108,111,118,101,100,119,97,115,116,101,48,48, +112,120,59,106,97,58,227,130,115,105,109,111,110,60,102,111,110,116,114,101,112, +108,121,109,101,101,116,115,117,110,116,101,114,99,104,101,97,112,116,105,103, +104,116,66,114,97,110,100,41,32,33,61,32,100,114,101,115,115,99,108,105,112,115, +114,111,111,109,115,111,110,107,101,121,109,111,98,105,108,109,97,105,110,46,78, +97,109,101,32,112,108,97,116,101,102,117,110,110,121,116,114,101,101,115,99,111, +109,47,34,49,46,106,112,103,119,109,111,100,101,112,97,114,97,109,83,84,65,82,84 +,108,101,102,116,32,105,100,100,101,110,44,32,50,48,49,41,59,10,125,10,102,111, +114,109,46,118,105,114,117,115,99,104,97,105,114,116,114,97,110,115,119,111,114, +115,116,80,97,103,101,115,105,116,105,111,110,112,97,116,99,104,60,33,45,45,10, +111,45,99,97,99,102,105,114,109,115,116,111,117,114,115,44,48,48,48,32,97,115, +105,97,110,105,43,43,41,123,97,100,111,98,101,39,41,91,48,93,105,100,61,49,48,98 +,111,116,104,59,109,101,110,117,32,46,50,46,109,105,46,112,110,103,34,107,101, +118,105,110,99,111,97,99,104,67,104,105,108,100,98,114,117,99,101,50,46,106,112, +103,85,82,76,41,43,46,106,112,103,124,115,117,105,116,101,115,108,105,99,101,104 +,97,114,114,121,49,50,48,34,32,115,119,101,101,116,116,114,62,13,10,110,97,109, +101,61,100,105,101,103,111,112,97,103,101,32,115,119,105,115,115,45,45,62,10,10, +35,102,102,102,59,34,62,76,111,103,46,99,111,109,34,116,114,101,97,116,115,104, +101,101,116,41,32,38,38,32,49,52,112,120,59,115,108,101,101,112,110,116,101,110, +116,102,105,108,101,100,106,97,58,227,131,105,100,61,34,99,78,97,109,101,34,119, +111,114,115,101,115,104,111,116,115,45,98,111,120,45,100,101,108,116,97,10,38, +108,116,59,98,101,97,114,115,58,52,56,90,60,100,97,116,97,45,114,117,114,97,108, +60,47,97,62,32,115,112,101,110,100,98,97,107,101,114,115,104,111,112,115,61,32, +34,34,59,112,104,112,34,62,99,116,105,111,110,49,51,112,120,59,98,114,105,97,110 +,104,101,108,108,111,115,105,122,101,61,111,61,37,50,70,32,106,111,105,110,109, +97,121,98,101,60,105,109,103,32,105,109,103,34,62,44,32,102,106,115,105,109,103, +34,32,34,41,91,48,93,77,84,111,112,66,84,121,112,101,34,110,101,119,108,121,68, +97,110,115,107,99,122,101,99,104,116,114,97,105,108,107,110,111,119,115,60,47, +104,53,62,102,97,113,34,62,122,104,45,99,110,49,48,41,59,10,45,49,34,41,59,116, +121,112,101,61,98,108,117,101,115,116,114,117,108,121,100,97,118,105,115,46,106, +115,39,59,62,13,10,60,33,115,116,101,101,108,32,121,111,117,32,104,50,62,13,10, +102,111,114,109,32,106,101,115,117,115,49,48,48,37,32,109,101,110,117,46,13,10,9 +,13,10,119,97,108,101,115,114,105,115,107,115,117,109,101,110,116,100,100,105, +110,103,98,45,108,105,107,116,101,97,99,104,103,105,102,34,32,118,101,103,97,115 +,100,97,110,115,107,101,101,115,116,105,115,104,113,105,112,115,117,111,109,105, +115,111,98,114,101,100,101,115,100,101,101,110,116,114,101,116,111,100,111,115, +112,117,101,100,101,97,195,177,111,115,101,115,116,195,161,116,105,101,110,101, +104,97,115,116,97,111,116,114,111,115,112,97,114,116,101,100,111,110,100,101,110 +,117,101,118,111,104,97,99,101,114,102,111,114,109,97,109,105,115,109,111,109, +101,106,111,114,109,117,110,100,111,97,113,117,195,173,100,195,173,97,115,115, +195,179,108,111,97,121,117,100,97,102,101,99,104,97,116,111,100,97,115,116,97, +110,116,111,109,101,110,111,115,100,97,116,111,115,111,116,114,97,115,115,105, +116,105,111,109,117,99,104,111,97,104,111,114,97,108,117,103,97,114,109,97,121, +111,114,101,115,116,111,115,104,111,114,97,115,116,101,110,101,114,97,110,116, +101,115,102,111,116,111,115,101,115,116,97,115,112,97,195,173,115,110,117,101, +118,97,115,97,108,117,100,102,111,114,111,115,109,101,100,105,111,113,117,105, +101,110,109,101,115,101,115,112,111,100,101,114,99,104,105,108,101,115,101,114, +195,161,118,101,99,101,115,100,101,99,105,114,106,111,115,195,169,101,115,116,97 +,114,118,101,110,116,97,103,114,117,112,111,104,101,99,104,111,101,108,108,111, +115,116,101,110,103,111,97,109,105,103,111,99,111,115,97,115,110,105,118,101,108 +,103,101,110,116,101,109,105,115,109,97,97,105,114,101,115,106,117,108,105,111, +116,101,109,97,115,104,97,99,105,97,102,97,118,111,114,106,117,110,105,111,108, +105,98,114,101,112,117,110,116,111,98,117,101,110,111,97,117,116,111,114,97,98, +114,105,108,98,117,101,110,97,116,101,120,116,111,109,97,114,122,111,115,97,98, +101,114,108,105,115,116,97,108,117,101,103,111,99,195,179,109,111,101,110,101, +114,111,106,117,101,103,111,112,101,114,195,186,104,97,98,101,114,101,115,116, +111,121,110,117,110,99,97,109,117,106,101,114,118,97,108,111,114,102,117,101,114 +,97,108,105,98,114,111,103,117,115,116,97,105,103,117,97,108,118,111,116,111,115 +,99,97,115,111,115,103,117,195,173,97,112,117,101,100,111,115,111,109,111,115,97 +,118,105,115,111,117,115,116,101,100,100,101,98,101,110,110,111,99,104,101,98, +117,115,99,97,102,97,108,116,97,101,117,114,111,115,115,101,114,105,101,100,105, +99,104,111,99,117,114,115,111,99,108,97,118,101,99,97,115,97,115,108,101,195,179 +,110,112,108,97,122,111,108,97,114,103,111,111,98,114,97,115,118,105,115,116,97, +97,112,111,121,111,106,117,110,116,111,116,114,97,116,97,118,105,115,116,111,99, +114,101,97,114,99,97,109,112,111,104,101,109,111,115,99,105,110,99,111,99,97,114 +,103,111,112,105,115,111,115,111,114,100,101,110,104,97,99,101,110,195,161,114, +101,97,100,105,115,99,111,112,101,100,114,111,99,101,114,99,97,112,117,101,100, +97,112,97,112,101,108,109,101,110,111,114,195,186,116,105,108,99,108,97,114,111, +106,111,114,103,101,99,97,108,108,101,112,111,110,101,114,116,97,114,100,101,110 +,97,100,105,101,109,97,114,99,97,115,105,103,117,101,101,108,108,97,115,115,105, +103,108,111,99,111,99,104,101,109,111,116,111,115,109,97,100,114,101,99,108,97, +115,101,114,101,115,116,111,110,105,195,177,111,113,117,101,100,97,112,97,115,97 +,114,98,97,110,99,111,104,105,106,111,115,118,105,97,106,101,112,97,98,108,111, +195,169,115,116,101,118,105,101,110,101,114,101,105,110,111,100,101,106,97,114, +102,111,110,100,111,99,97,110,97,108,110,111,114,116,101,108,101,116,114,97,99, +97,117,115,97,116,111,109,97,114,109,97,110,111,115,108,117,110,101,115,97,117, +116,111,115,118,105,108,108,97,118,101,110,100,111,112,101,115,97,114,116,105, +112,111,115,116,101,110,103,97,109,97,114,99,111,108,108,101,118,97,112,97,100, +114,101,117,110,105,100,111,118,97,109,111,115,122,111,110,97,115,97,109,98,111, +115,98,97,110,100,97,109,97,114,105,97,97,98,117,115,111,109,117,99,104,97,115, +117,98,105,114,114,105,111,106,97,118,105,118,105,114,103,114,97,100,111,99,104, +105,99,97,97,108,108,195,173,106,111,118,101,110,100,105,99,104,97,101,115,116, +97,110,116,97,108,101,115,115,97,108,105,114,115,117,101,108,111,112,101,115,111 +,115,102,105,110,101,115,108,108,97,109,97,98,117,115,99,111,195,169,115,116,97, +108,108,101,103,97,110,101,103,114,111,112,108,97,122,97,104,117,109,111,114,112 +,97,103,97,114,106,117,110,116,97,100,111,98,108,101,105,115,108,97,115,98,111, +108,115,97,98,97,195,177,111,104,97,98,108,97,108,117,99,104,97,195,129,114,101, +97,100,105,99,101,110,106,117,103,97,114,110,111,116,97,115,118,97,108,108,101, +97,108,108,195,161,99,97,114,103,97,100,111,108,111,114,97,98,97,106,111,101,115 +,116,195,169,103,117,115,116,111,109,101,110,116,101,109,97,114,105,111,102,105, +114,109,97,99,111,115,116,111,102,105,99,104,97,112,108,97,116,97,104,111,103,97 +,114,97,114,116,101,115,108,101,121,101,115,97,113,117,101,108,109,117,115,101, +111,98,97,115,101,115,112,111,99,111,115,109,105,116,97,100,99,105,101,108,111, +99,104,105,99,111,109,105,101,100,111,103,97,110,97,114,115,97,110,116,111,101, +116,97,112,97,100,101,98,101,115,112,108,97,121,97,114,101,100,101,115,115,105, +101,116,101,99,111,114,116,101,99,111,114,101,97,100,117,100,97,115,100,101,115, +101,111,118,105,101,106,111,100,101,115,101,97,97,103,117,97,115,38,113,117,111, +116,59,100,111,109,97,105,110,99,111,109,109,111,110,115,116,97,116,117,115,101, +118,101,110,116,115,109,97,115,116,101,114,115,121,115,116,101,109,97,99,116,105 +,111,110,98,97,110,110,101,114,114,101,109,111,118,101,115,99,114,111,108,108, +117,112,100,97,116,101,103,108,111,98,97,108,109,101,100,105,117,109,102,105,108 +,116,101,114,110,117,109,98,101,114,99,104,97,110,103,101,114,101,115,117,108, +116,112,117,98,108,105,99,115,99,114,101,101,110,99,104,111,111,115,101,110,111, +114,109,97,108,116,114,97,118,101,108,105,115,115,117,101,115,115,111,117,114,99 +,101,116,97,114,103,101,116,115,112,114,105,110,103,109,111,100,117,108,101,109, +111,98,105,108,101,115,119,105,116,99,104,112,104,111,116,111,115,98,111,114,100 +,101,114,114,101,103,105,111,110,105,116,115,101,108,102,115,111,99,105,97,108, +97,99,116,105,118,101,99,111,108,117,109,110,114,101,99,111,114,100,102,111,108, +108,111,119,116,105,116,108,101,62,101,105,116,104,101,114,108,101,110,103,116, +104,102,97,109,105,108,121,102,114,105,101,110,100,108,97,121,111,117,116,97,117 +,116,104,111,114,99,114,101,97,116,101,114,101,118,105,101,119,115,117,109,109, +101,114,115,101,114,118,101,114,112,108,97,121,101,100,112,108,97,121,101,114, +101,120,112,97,110,100,112,111,108,105,99,121,102,111,114,109,97,116,100,111,117 +,98,108,101,112,111,105,110,116,115,115,101,114,105,101,115,112,101,114,115,111, +110,108,105,118,105,110,103,100,101,115,105,103,110,109,111,110,116,104,115,102, +111,114,99,101,115,117,110,105,113,117,101,119,101,105,103,104,116,112,101,111, +112,108,101,101,110,101,114,103,121,110,97,116,117,114,101,115,101,97,114,99,104 +,102,105,103,117,114,101,104,97,118,105,110,103,99,117,115,116,111,109,111,102, +102,115,101,116,108,101,116,116,101,114,119,105,110,100,111,119,115,117,98,109, +105,116,114,101,110,100,101,114,103,114,111,117,112,115,117,112,108,111,97,100, +104,101,97,108,116,104,109,101,116,104,111,100,118,105,100,101,111,115,115,99, +104,111,111,108,102,117,116,117,114,101,115,104,97,100,111,119,100,101,98,97,116 +,101,118,97,108,117,101,115,79,98,106,101,99,116,111,116,104,101,114,115,114,105 +,103,104,116,115,108,101,97,103,117,101,99,104,114,111,109,101,115,105,109,112, +108,101,110,111,116,105,99,101,115,104,97,114,101,100,101,110,100,105,110,103, +115,101,97,115,111,110,114,101,112,111,114,116,111,110,108,105,110,101,115,113, +117,97,114,101,98,117,116,116,111,110,105,109,97,103,101,115,101,110,97,98,108, +101,109,111,118,105,110,103,108,97,116,101,115,116,119,105,110,116,101,114,70, +114,97,110,99,101,112,101,114,105,111,100,115,116,114,111,110,103,114,101,112, +101,97,116,76,111,110,100,111,110,100,101,116,97,105,108,102,111,114,109,101,100 +,100,101,109,97,110,100,115,101,99,117,114,101,112,97,115,115,101,100,116,111, +103,103,108,101,112,108,97,99,101,115,100,101,118,105,99,101,115,116,97,116,105, +99,99,105,116,105,101,115,115,116,114,101,97,109,121,101,108,108,111,119,97,116, +116,97,99,107,115,116,114,101,101,116,102,108,105,103,104,116,104,105,100,100, +101,110,105,110,102,111,34,62,111,112,101,110,101,100,117,115,101,102,117,108, +118,97,108,108,101,121,99,97,117,115,101,115,108,101,97,100,101,114,115,101,99, +114,101,116,115,101,99,111,110,100,100,97,109,97,103,101,115,112,111,114,116,115 +,101,120,99,101,112,116,114,97,116,105,110,103,115,105,103,110,101,100,116,104, +105,110,103,115,101,102,102,101,99,116,102,105,101,108,100,115,115,116,97,116, +101,115,111,102,102,105,99,101,118,105,115,117,97,108,101,100,105,116,111,114, +118,111,108,117,109,101,82,101,112,111,114,116,109,117,115,101,117,109,109,111, +118,105,101,115,112,97,114,101,110,116,97,99,99,101,115,115,109,111,115,116,108, +121,109,111,116,104,101,114,34,32,105,100,61,34,109,97,114,107,101,116,103,114, +111,117,110,100,99,104,97,110,99,101,115,117,114,118,101,121,98,101,102,111,114, +101,115,121,109,98,111,108,109,111,109,101,110,116,115,112,101,101,99,104,109, +111,116,105,111,110,105,110,115,105,100,101,109,97,116,116,101,114,67,101,110, +116,101,114,111,98,106,101,99,116,101,120,105,115,116,115,109,105,100,100,108, +101,69,117,114,111,112,101,103,114,111,119,116,104,108,101,103,97,99,121,109,97, +110,110,101,114,101,110,111,117,103,104,99,97,114,101,101,114,97,110,115,119,101 +,114,111,114,105,103,105,110,112,111,114,116,97,108,99,108,105,101,110,116,115, +101,108,101,99,116,114,97,110,100,111,109,99,108,111,115,101,100,116,111,112,105 +,99,115,99,111,109,105,110,103,102,97,116,104,101,114,111,112,116,105,111,110, +115,105,109,112,108,121,114,97,105,115,101,100,101,115,99,97,112,101,99,104,111, +115,101,110,99,104,117,114,99,104,100,101,102,105,110,101,114,101,97,115,111,110 +,99,111,114,110,101,114,111,117,116,112,117,116,109,101,109,111,114,121,105,102, +114,97,109,101,112,111,108,105,99,101,109,111,100,101,108,115,78,117,109,98,101, +114,100,117,114,105,110,103,111,102,102,101,114,115,115,116,121,108,101,115,107, +105,108,108,101,100,108,105,115,116,101,100,99,97,108,108,101,100,115,105,108, +118,101,114,109,97,114,103,105,110,100,101,108,101,116,101,98,101,116,116,101, +114,98,114,111,119,115,101,108,105,109,105,116,115,71,108,111,98,97,108,115,105, +110,103,108,101,119,105,100,103,101,116,99,101,110,116,101,114,98,117,100,103, +101,116,110,111,119,114,97,112,99,114,101,100,105,116,99,108,97,105,109,115,101, +110,103,105,110,101,115,97,102,101,116,121,99,104,111,105,99,101,115,112,105,114 +,105,116,45,115,116,121,108,101,115,112,114,101,97,100,109,97,107,105,110,103, +110,101,101,100,101,100,114,117,115,115,105,97,112,108,101,97,115,101,101,120, +116,101,110,116,83,99,114,105,112,116,98,114,111,107,101,110,97,108,108,111,119, +115,99,104,97,114,103,101,100,105,118,105,100,101,102,97,99,116,111,114,109,101, +109,98,101,114,45,98,97,115,101,100,116,104,101,111,114,121,99,111,110,102,105, +103,97,114,111,117,110,100,119,111,114,107,101,100,104,101,108,112,101,100,67, +104,117,114,99,104,105,109,112,97,99,116,115,104,111,117,108,100,97,108,119,97, +121,115,108,111,103,111,34,32,98,111,116,116,111,109,108,105,115,116,34,62,41, +123,118,97,114,32,112,114,101,102,105,120,111,114,97,110,103,101,72,101,97,100, +101,114,46,112,117,115,104,40,99,111,117,112,108,101,103,97,114,100,101,110,98, +114,105,100,103,101,108,97,117,110,99,104,82,101,118,105,101,119,116,97,107,105, +110,103,118,105,115,105,111,110,108,105,116,116,108,101,100,97,116,105,110,103, +66,117,116,116,111,110,98,101,97,117,116,121,116,104,101,109,101,115,102,111,114 +,103,111,116,83,101,97,114,99,104,97,110,99,104,111,114,97,108,109,111,115,116, +108,111,97,100,101,100,67,104,97,110,103,101,114,101,116,117,114,110,115,116,114 +,105,110,103,114,101,108,111,97,100,77,111,98,105,108,101,105,110,99,111,109,101 +,115,117,112,112,108,121,83,111,117,114,99,101,111,114,100,101,114,115,118,105, +101,119,101,100,38,110,98,115,112,59,99,111,117,114,115,101,65,98,111,117,116,32 +,105,115,108,97,110,100,60,104,116,109,108,32,99,111,111,107,105,101,110,97,109, +101,61,34,97,109,97,122,111,110,109,111,100,101,114,110,97,100,118,105,99,101, +105,110,60,47,97,62,58,32,84,104,101,32,100,105,97,108,111,103,104,111,117,115, +101,115,66,69,71,73,78,32,77,101,120,105,99,111,115,116,97,114,116,115,99,101, +110,116,114,101,104,101,105,103,104,116,97,100,100,105,110,103,73,115,108,97,110 +,100,97,115,115,101,116,115,69,109,112,105,114,101,83,99,104,111,111,108,101,102 +,102,111,114,116,100,105,114,101,99,116,110,101,97,114,108,121,109,97,110,117,97 +,108,83,101,108,101,99,116,46,10,10,79,110,101,106,111,105,110,101,100,109,101, +110,117,34,62,80,104,105,108,105,112,97,119,97,114,100,115,104,97,110,100,108, +101,105,109,112,111,114,116,79,102,102,105,99,101,114,101,103,97,114,100,115,107 +,105,108,108,115,110,97,116,105,111,110,83,112,111,114,116,115,100,101,103,114, +101,101,119,101,101,107,108,121,32,40,101,46,103,46,98,101,104,105,110,100,100, +111,99,116,111,114,108,111,103,103,101,100,117,110,105,116,101,100,60,47,98,62, +60,47,98,101,103,105,110,115,112,108,97,110,116,115,97,115,115,105,115,116,97, +114,116,105,115,116,105,115,115,117,101,100,51,48,48,112,120,124,99,97,110,97, +100,97,97,103,101,110,99,121,115,99,104,101,109,101,114,101,109,97,105,110,66, +114,97,122,105,108,115,97,109,112,108,101,108,111,103,111,34,62,98,101,121,111, +110,100,45,115,99,97,108,101,97,99,99,101,112,116,115,101,114,118,101,100,109,97 +,114,105,110,101,70,111,111,116,101,114,99,97,109,101,114,97,60,47,104,49,62,10, +95,102,111,114,109,34,108,101,97,118,101,115,115,116,114,101,115,115,34,32,47,62 +,13,10,46,103,105,102,34,32,111,110,108,111,97,100,108,111,97,100,101,114,79,120 +,102,111,114,100,115,105,115,116,101,114,115,117,114,118,105,118,108,105,115,116 +,101,110,102,101,109,97,108,101,68,101,115,105,103,110,115,105,122,101,61,34,97, +112,112,101,97,108,116,101,120,116,34,62,108,101,118,101,108,115,116,104,97,110, +107,115,104,105,103,104,101,114,102,111,114,99,101,100,97,110,105,109,97,108,97, +110,121,111,110,101,65,102,114,105,99,97,97,103,114,101,101,100,114,101,99,101, +110,116,80,101,111,112,108,101,60,98,114,32,47,62,119,111,110,100,101,114,112, +114,105,99,101,115,116,117,114,110,101,100,124,124,32,123,125,59,109,97,105,110, +34,62,105,110,108,105,110,101,115,117,110,100,97,121,119,114,97,112,34,62,102,97 +,105,108,101,100,99,101,110,115,117,115,109,105,110,117,116,101,98,101,97,99,111 +,110,113,117,111,116,101,115,49,53,48,112,120,124,101,115,116,97,116,101,114,101 +,109,111,116,101,101,109,97,105,108,34,108,105,110,107,101,100,114,105,103,104, +116,59,115,105,103,110,97,108,102,111,114,109,97,108,49,46,104,116,109,108,115, +105,103,110,117,112,112,114,105,110,99,101,102,108,111,97,116,58,46,112,110,103, +34,32,102,111,114,117,109,46,65,99,99,101,115,115,112,97,112,101,114,115,115,111 +,117,110,100,115,101,120,116,101,110,100,72,101,105,103,104,116,115,108,105,100, +101,114,85,84,70,45,56,34,38,97,109,112,59,32,66,101,102,111,114,101,46,32,87, +105,116,104,115,116,117,100,105,111,111,119,110,101,114,115,109,97,110,97,103, +101,112,114,111,102,105,116,106,81,117,101,114,121,97,110,110,117,97,108,112,97, +114,97,109,115,98,111,117,103,104,116,102,97,109,111,117,115,103,111,111,103,108 +,101,108,111,110,103,101,114,105,43,43,41,32,123,105,115,114,97,101,108,115,97, +121,105,110,103,100,101,99,105,100,101,104,111,109,101,34,62,104,101,97,100,101, +114,101,110,115,117,114,101,98,114,97,110,99,104,112,105,101,99,101,115,98,108, +111,99,107,59,115,116,97,116,101,100,116,111,112,34,62,60,114,97,99,105,110,103, +114,101,115,105,122,101,45,45,38,103,116,59,112,97,99,105,116,121,115,101,120, +117,97,108,98,117,114,101,97,117,46,106,112,103,34,32,49,48,44,48,48,48,111,98, +116,97,105,110,116,105,116,108,101,115,97,109,111,117,110,116,44,32,73,110,99,46 +,99,111,109,101,100,121,109,101,110,117,34,32,108,121,114,105,99,115,116,111,100 +,97,121,46,105,110,100,101,101,100,99,111,117,110,116,121,95,108,111,103,111,46, +70,97,109,105,108,121,108,111,111,107,101,100,77,97,114,107,101,116,108,115,101, +32,105,102,80,108,97,121,101,114,116,117,114,107,101,121,41,59,118,97,114,32,102 +,111,114,101,115,116,103,105,118,105,110,103,101,114,114,111,114,115,68,111,109, +97,105,110,125,101,108,115,101,123,105,110,115,101,114,116,66,108,111,103,60,47, +102,111,111,116,101,114,108,111,103,105,110,46,102,97,115,116,101,114,97,103,101 +,110,116,115,60,98,111,100,121,32,49,48,112,120,32,48,112,114,97,103,109,97,102, +114,105,100,97,121,106,117,110,105,111,114,100,111,108,108,97,114,112,108,97,99, +101,100,99,111,118,101,114,115,112,108,117,103,105,110,53,44,48,48,48,32,112,97, +103,101,34,62,98,111,115,116,111,110,46,116,101,115,116,40,97,118,97,116,97,114, +116,101,115,116,101,100,95,99,111,117,110,116,102,111,114,117,109,115,115,99,104 +,101,109,97,105,110,100,101,120,44,102,105,108,108,101,100,115,104,97,114,101, +115,114,101,97,100,101,114,97,108,101,114,116,40,97,112,112,101,97,114,83,117,98 +,109,105,116,108,105,110,101,34,62,98,111,100,121,34,62,10,42,32,84,104,101,84, +104,111,117,103,104,115,101,101,105,110,103,106,101,114,115,101,121,78,101,119, +115,60,47,118,101,114,105,102,121,101,120,112,101,114,116,105,110,106,117,114, +121,119,105,100,116,104,61,67,111,111,107,105,101,83,84,65,82,84,32,97,99,114, +111,115,115,95,105,109,97,103,101,116,104,114,101,97,100,110,97,116,105,118,101, +112,111,99,107,101,116,98,111,120,34,62,10,83,121,115,116,101,109,32,68,97,118, +105,100,99,97,110,99,101,114,116,97,98,108,101,115,112,114,111,118,101,100,65, +112,114,105,108,32,114,101,97,108,108,121,100,114,105,118,101,114,105,116,101, +109,34,62,109,111,114,101,34,62,98,111,97,114,100,115,99,111,108,111,114,115,99, +97,109,112,117,115,102,105,114,115,116,32,124,124,32,91,93,59,109,101,100,105,97 +,46,103,117,105,116,97,114,102,105,110,105,115,104,119,105,100,116,104,58,115, +104,111,119,101,100,79,116,104,101,114,32,46,112,104,112,34,32,97,115,115,117, +109,101,108,97,121,101,114,115,119,105,108,115,111,110,115,116,111,114,101,115, +114,101,108,105,101,102,115,119,101,100,101,110,67,117,115,116,111,109,101,97, +115,105,108,121,32,121,111,117,114,32,83,116,114,105,110,103,10,10,87,104,105, +108,116,97,121,108,111,114,99,108,101,97,114,58,114,101,115,111,114,116,102,114, +101,110,99,104,116,104,111,117,103,104,34,41,32,43,32,34,60,98,111,100,121,62,98 +,117,121,105,110,103,98,114,97,110,100,115,77,101,109,98,101,114,110,97,109,101, +34,62,111,112,112,105,110,103,115,101,99,116,111,114,53,112,120,59,34,62,118,115 +,112,97,99,101,112,111,115,116,101,114,109,97,106,111,114,32,99,111,102,102,101, +101,109,97,114,116,105,110,109,97,116,117,114,101,104,97,112,112,101,110,60,47, +110,97,118,62,107,97,110,115,97,115,108,105,110,107,34,62,73,109,97,103,101,115, +61,102,97,108,115,101,119,104,105,108,101,32,104,115,112,97,99,101,48,38,97,109, +112,59,32,10,10,73,110,32,32,112,111,119,101,114,80,111,108,115,107,105,45,99, +111,108,111,114,106,111,114,100,97,110,66,111,116,116,111,109,83,116,97,114,116, +32,45,99,111,117,110,116,50,46,104,116,109,108,110,101,119,115,34,62,48,49,46, +106,112,103,79,110,108,105,110,101,45,114,105,103,104,116,109,105,108,108,101, +114,115,101,110,105,111,114,73,83,66,78,32,48,48,44,48,48,48,32,103,117,105,100, +101,115,118,97,108,117,101,41,101,99,116,105,111,110,114,101,112,97,105,114,46, +120,109,108,34,32,32,114,105,103,104,116,115,46,104,116,109,108,45,98,108,111,99 +,107,114,101,103,69,120,112,58,104,111,118,101,114,119,105,116,104,105,110,118, +105,114,103,105,110,112,104,111,110,101,115,60,47,116,114,62,13,117,115,105,110, +103,32,10,9,118,97,114,32,62,39,41,59,10,9,60,47,116,100,62,10,60,47,116,114,62, +10,98,97,104,97,115,97,98,114,97,115,105,108,103,97,108,101,103,111,109,97,103, +121,97,114,112,111,108,115,107,105,115,114,112,115,107,105,216,177,216,175,217, +136,228,184,173,230,150,135,231,174,128,228,189,147,231,185,129,233,171,148,228, +191,161,230,129,175,228,184,173,229,155,189,230,136,145,228,187,172,228,184,128, +228,184,170,229,133,172,229,143,184,231,174,161,231,144,134,232,174,186,229,157, +155,229,143,175,228,187,165,230,156,141,229,138,161,230,151,182,233,151,180,228, +184,170,228,186,186,228,186,167,229,147,129,232,135,170,229,183,177,228,188,129, +228,184,154,230,159,165,231,156,139,229,183,165,228,189,156,232,129,148,231,179, +187,230,178,161,230,156,137,231,189,145,231,171,153,230,137,128,230,156,137,232, +175,132,232,174,186,228,184,173,229,191,131,230,150,135,231,171,160,231,148,168, +230,136,183,233,166,150,233,161,181,228,189,156,232,128,133,230,138,128,230,156, +175,233,151,174,233,162,152,231,155,184,229,133,179,228,184,139,232,189,189,230, +144,156,231,180,162,228,189,191,231,148,168,232,189,175,228,187,182,229,156,168, +231,186,191,228,184,187,233,162,152,232,181,132,230,150,153,232,167,134,233,162, +145,229,155,158,229,164,141,230,179,168,229,134,140,231,189,145,231,187,156,230, +148,182,232,151,143,229,134,133,229,174,185,230,142,168,232,141,144,229,184,130, +229,156,186,230,182,136,230,129,175,231,169,186,233,151,180,229,143,145,229,184, +131,228,187,128,228,185,136,229,165,189,229,143,139,231,148,159,230,180,187,229, +155,190,231,137,135,229,143,145,229,177,149,229,166,130,230,158,156,230,137,139, +230,156,186,230,150,176,233,151,187,230,156,128,230,150,176,230,150,185,229,188, +143,229,140,151,228,186,172,230,143,144,228,190,155,229,133,179,228,186,142,230, +155,180,229,164,154,232,191,153,228,184,170,231,179,187,231,187,159,231,159,165, +233,129,147,230,184,184,230,136,143,229,185,191,229,145,138,229,133,182,228,187, +150,229,143,145,232,161,168,229,174,137,229,133,168,231,172,172,228,184,128,228, +188,154,229,145,152,232,191,155,232,161,140,231,130,185,229,135,187,231,137,136, +230,157,131,231,148,181,229,173,144,228,184,150,231,149,140,232,174,190,232,174, +161,229,133,141,232,180,185,230,149,153,232,130,178,229,138,160,229,133,165,230, +180,187,229,138,168,228,187,150,228,187,172,229,149,134,229,147,129,229,141,154, +229,174,162,231,142,176,229,156,168,228,184,138,230,181,183,229,166,130,228,189, +149,229,183,178,231,187,143,231,149,153,232,168,128,232,175,166,231,187,134,231, +164,190,229,140,186,231,153,187,229,189,149,230,156,172,231,171,153,233,156,128, +232,166,129,228,187,183,230,160,188,230,148,175,230,140,129,229,155,189,233,153, +133,233,147,190,230,142,165,229,155,189,229,174,182,229,187,186,232,174,190,230, +156,139,229,143,139,233,152,133,232,175,187,230,179,149,229,190,139,228,189,141, +231,189,174,231,187,143,230,181,142,233,128,137,230,139,169,232,191,153,230,160, +183,229,189,147,229,137,141,229,136,134,231,177,187,230,142,146,232,161,140,229, +155,160,228,184,186,228,186,164,230,152,147,230,156,128,229,144,142,233,159,179, +228,185,144,228,184,141,232,131,189,233,128,154,232,191,135,232,161,140,228,184, +154,231,167,145,230,138,128,229,143,175,232,131,189,232,174,190,229,164,135,229, +144,136,228,189,156,229,164,167,229,174,182,231,164,190,228,188,154,231,160,148, +231,169,182,228,184,147,228,184,154,229,133,168,233,131,168,233,161,185,231,155, +174,232,191,153,233,135,140,232,191,152,230,152,175,229,188,128,229,167,139,230, +131,133,229,134,181,231,148,181,232,132,145,230,150,135,228,187,182,229,147,129, +231,137,140,229,184,174,229,138,169,230,150,135,229,140,150,232,181,132,230,186, +144,229,164,167,229,173,166,229,173,166,228,185,160,229,156,176,229,157,128,230, +181,143,232,167,136,230,138,149,232,181,132,229,183,165,231,168,139,232,166,129, +230,177,130,230,128,142,228,185,136,230,151,182,229,128,153,229,138,159,232,131, +189,228,184,187,232,166,129,231,155,174,229,137,141,232,181,132,232,174,175,229, +159,142,229,184,130,230,150,185,230,179,149,231,148,181,229,189,177,230,139,155, +232,129,152,229,163,176,230,152,142,228,187,187,228,189,149,229,129,165,229,186, +183,230,149,176,230,141,174,231,190,142,229,155,189,230,177,189,232,189,166,228, +187,139,231,187,141,228,189,134,230,152,175,228,186,164,230,181,129,231,148,159, +228,186,167,230,137,128,228,187,165,231,148,181,232,175,157,230,152,190,231,164, +186,228,184,128,228,186,155,229,141,149,228,189,141,228,186,186,229,145,152,229, +136,134,230,158,144,229,156,176,229,155,190,230,151,133,230,184,184,229,183,165, +229,133,183,229,173,166,231,148,159,231,179,187,229,136,151,231,189,145,229,143, +139,229,184,150,229,173,144,229,175,134,231,160,129,233,162,145,233,129,147,230, +142,167,229,136,182,229,156,176,229,140,186,229,159,186,230,156,172,229,133,168, +229,155,189,231,189,145,228,184,138,233,135,141,232,166,129,231,172,172,228,186, +140,229,150,156,230,172,162,232,191,155,229,133,165,229,143,139,230,131,133,232, +191,153,228,186,155,232,128,131,232,175,149,229,143,145,231,142,176,229,159,185, +232,174,173,228,187,165,228,184,138,230,148,191,229,186,156,230,136,144,228,184, +186,231,142,175,229,162,131,233,166,153,230,184,175,229,144,140,230,151,182,229, +168,177,228,185,144,229,143,145,233,128,129,228,184,128,229,174,154,229,188,128, +229,143,145,228,189,156,229,147,129,230,160,135,229,135,134,230,172,162,232,191, +142,232,167,163,229,134,179,229,156,176,230,150,185,228,184,128,228,184,139,228, +187,165,229,143,138,232,180,163,228,187,187,230,136,150,232,128,133,229,174,162, +230,136,183,228,187,163,232,161,168,231,167,175,229,136,134,229,165,179,228,186, +186,230,149,176,231,160,129,233,148,128,229,148,174,229,135,186,231,142,176,231, +166,187,231,186,191,229,186,148,231,148,168,229,136,151,232,161,168,228,184,141, +229,144,140,231,188,150,232,190,145,231,187,159,232,174,161,230,159,165,232,175, +162,228,184,141,232,166,129,230,156,137,229,133,179,230,156,186,230,158,132,229, +190,136,229,164,154,230,146,173,230,148,190,231,187,132,231,187,135,230,148,191, +231,173,150,231,155,180,230,142,165,232,131,189,229,138,155,230,157,165,230,186, +144,230,153,130,233,150,147,231,156,139,229,136,176,231,131,173,233,151,168,229, +133,179,233,148,174,228,184,147,229,140,186,233,157,158,229,184,184,232,139,177, +232,175,173,231,153,190,229,186,166,229,184,140,230,156,155,231,190,142,229,165, +179,230,175,148,232,190,131,231,159,165,232,175,134,232,167,132,229,174,154,229, +187,186,232,174,174,233,131,168,233,151,168,230,132,143,232,167,129,231,178,190, +229,189,169,230,151,165,230,156,172,230,143,144,233,171,152,229,143,145,232,168, +128,230,150,185,233,157,162,229,159,186,233,135,145,229,164,132,231,144,134,230, +157,131,233,153,144,229,189,177,231,137,135,233,147,182,232,161,140,232,191,152, +230,156,137,229,136,134,228,186,171,231,137,169,229,147,129,231,187,143,232,144, +165,230,183,187,229,138,160,228,184,147,229,174,182,232,191,153,231,167,141,232, +175,157,233,162,152,232,181,183,230,157,165,228,184,154,229,138,161,229,133,172, +229,145,138,232,174,176,229,189,149,231,174,128,228,187,139,232,180,168,233,135, +143,231,148,183,228,186,186,229,189,177,229,147,141,229,188,149,231,148,168,230, +138,165,229,145,138,233,131,168,229,136,134,229,191,171,233,128,159,229,146,168, +232,175,162,230,151,182,229,176,154,230,179,168,230,132,143,231,148,179,232,175, +183,229,173,166,230,160,161,229,186,148,232,175,165,229,142,134,229,143,178,229, +143,170,230,152,175,232,191,148,229,155,158,232,180,173,228,185,176,229,144,141, +231,167,176,228,184,186,228,186,134,230,136,144,229,138,159,232,175,180,230,152, +142,228,190,155,229,186,148,229,173,169,229,173,144,228,184,147,233,162,152,231, +168,139,229,186,143,228,184,128,232,136,172,230,156,131,229,147,161,229,143,170, +230,156,137,229,133,182,229,174,131,228,191,157,230,138,164,232,128,140,228,184, +148,228,187,138,229,164,169,231,170,151,229,143,163,229,138,168,230,128,129,231, +138,182,230,128,129,231,137,185,229,136,171,232,174,164,228,184,186,229,191,133, +233,161,187,230,155,180,230,150,176,229,176,143,232,175,180,230,136,145,229,128, +145,228,189,156,228,184,186,229,170,146,228,189,147,229,140,133,230,139,172,233, +130,163,228,185,136,228,184,128,230,160,183,229,155,189,229,134,133,230,152,175, +229,144,166,230,160,185,230,141,174,231,148,181,232,167,134,229,173,166,233,153, +162,229,133,183,230,156,137,232,191,135,231,168,139,231,148,177,228,186,142,228, +186,186,230,137,141,229,135,186,230,157,165,228,184,141,232,191,135,230,173,163, +229,156,168,230,152,142,230,152,159,230,149,133,228,186,139,229,133,179,231,179, +187,230,160,135,233,162,152,229,149,134,229,138,161,232,190,147,229,133,165,228, +184,128,231,155,180,229,159,186,231,161,128,230,149,153,229,173,166,228,186,134, +232,167,163,229,187,186,231,173,145,231,187,147,230,158,156,229,133,168,231,144, +131,233,128,154,231,159,165,232,174,161,229,136,146,229,175,185,228,186,142,232, +137,186,230,156,175,231,155,184,229,134,140,229,143,145,231,148,159,231,156,159, +231,154,132,229,187,186,231,171,139,231,173,137,231,186,167,231,177,187,229,158, +139,231,187,143,233,170,140,229,174,158,231,142,176,229,136,182,228,189,156,230, +157,165,232,135,170,230,160,135,231,173,190,228,187,165,228,184,139,229,142,159, +229,136,155,230,151,160,230,179,149,229,133,182,228,184,173,229,128,139,228,186, +186,228,184,128,229,136,135,230,140,135,229,141,151,229,133,179,233,151,173,233, +155,134,229,155,162,231,172,172,228,184,137,229,133,179,230,179,168,229,155,160, +230,173,164,231,133,167,231,137,135,230,183,177,229,156,179,229,149,134,228,184, +154,229,185,191,229,183,158,230,151,165,230,156,159,233,171,152,231,186,167,230, +156,128,232,191,145,231,187,188,229,144,136,232,161,168,231,164,186,228,184,147, +232,190,145,232,161,140,228,184,186,228,186,164,233,128,154,232,175,132,228,187, +183,232,167,137,229,190,151,231,178,190,229,141,142,229,174,182,229,186,173,229, +174,140,230,136,144,230,132,159,232,167,137,229,174,137,232,163,133,229,190,151, +229,136,176,233,130,174,228,187,182,229,136,182,229,186,166,233,163,159,229,147, +129,232,153,189,231,132,182,232,189,172,232,189,189,230,138,165,228,187,183,232, +174,176,232,128,133,230,150,185,230,161,136,232,161,140,230,148,191,228,186,186, +230,176,145,231,148,168,229,147,129,228,184,156,232,165,191,230,143,144,229,135, +186,233,133,146,229,186,151,231,132,182,229,144,142,228,187,152,230,172,190,231, +131,173,231,130,185,228,187,165,229,137,141,229,174,140,229,133,168,229,143,145, +229,184,150,232,174,190,231,189,174,233,162,134,229,175,188,229,183,165,228,184, +154,229,140,187,233,153,162,231,156,139,231,156,139,231,187,143,229,133,184,229, +142,159,229,155,160,229,185,179,229,143,176,229,144,132,231,167,141,229,162,158, +229,138,160,230,157,144,230,150,153,230,150,176,229,162,158,228,185,139,229,144, +142,232,129,140,228,184,154,230,149,136,230,158,156,228,187,138,229,185,180,232, +174,186,230,150,135,230,136,145,229,155,189,229,145,138,232,175,137,231,137,136, +228,184,187,228,191,174,230,148,185,229,143,130,228,184,142,230,137,147,229,141, +176,229,191,171,228,185,144,230,156,186,230,162,176,232,167,130,231,130,185,229, +173,152,229,156,168,231,178,190,231,165,158,232,142,183,229,190,151,229,136,169, +231,148,168,231,187,167,231,187,173,228,189,160,228,187,172,232,191,153,228,185, +136,230,168,161,229,188,143,232,175,173,232,168,128,232,131,189,229,164,159,233, +155,133,232,153,142,230,147,141,228,189,156,233,163,142,230,160,188,228,184,128, +232,181,183,231,167,145,229,173,166,228,189,147,232,130,178,231,159,173,228,191, +161,230,157,161,228,187,182,230,178,187,231,150,151,232,191,144,229,138,168,228, +186,167,228,184,154,228,188,154,232,174,174,229,175,188,232,136,170,229,133,136, +231,148,159,232,129,148,231,155,159,229,143,175,230,152,175,229,149,143,233,161, +140,231,187,147,230,158,132,228,189,156,231,148,168,232,176,131,230,159,165,232, +179,135,230,150,153,232,135,170,229,138,168,232,180,159,232,180,163,229,134,156, +228,184,154,232,174,191,233,151,174,229,174,158,230,150,189,230,142,165,229,143, +151,232,174,168,232,174,186,233,130,163,228,184,170,229,143,141,233,166,136,229, +138,160,229,188,186,229,165,179,230,128,167,232,140,131,229,155,180,230,156,141, +229,139,153,228,188,145,233,151,178,228,187,138,230,151,165,229,174,162,230,156, +141,232,167,128,231,156,139,229,143,130,229,138,160,231,154,132,232,175,157,228, +184,128,231,130,185,228,191,157,232,175,129,229,155,190,228,185,166,230,156,137, +230,149,136,230,181,139,232,175,149,231,167,187,229,138,168,230,137,141,232,131, +189,229,134,179,229,174,154,232,130,161,231,165,168,228,184,141,230,150,173,233, +156,128,230,177,130,228,184,141,229,190,151,229,138,158,230,179,149,228,185,139, +233,151,180,233,135,135,231,148,168,232,144,165,233,148,128,230,138,149,232,175, +137,231,155,174,230,160,135,231,136,177,230,131,133,230,145,132,229,189,177,230, +156,137,228,186,155,232,164,135,232,163,189,230,150,135,229,173,166,230,156,186, +228,188,154,230,149,176,229,173,151,232,163,133,228,191,174,232,180,173,231,137, +169,229,134,156,230,157,145,229,133,168,233,157,162,231,178,190,229,147,129,229, +133,182,229,174,158,228,186,139,230,131,133,230,176,180,229,185,179,230,143,144, +231,164,186,228,184,138,229,184,130,232,176,162,232,176,162,230,153,174,233,128, +154,230,149,153,229,184,136,228,184,138,228,188,160,231,177,187,229,136,171,230, +173,140,230,155,178,230,139,165,230,156,137,229,136,155,230,150,176,233,133,141, +228,187,182,229,143,170,232,166,129,230,151,182,228,187,163,232,179,135,232,168, +138,232,190,190,229,136,176,228,186,186,231,148,159,232,174,162,233,152,133,232, +128,129,229,184,136,229,177,149,231,164,186,229,191,131,231,144,134,232,180,180, +229,173,144,231,182,178,231,171,153,228,184,187,233,161,140,232,135,170,231,132, +182,231,186,167,229,136,171,231,174,128,229,141,149,230,148,185,233,157,169,233, +130,163,228,186,155,230,157,165,232,175,180,230,137,147,229,188,128,228,187,163, +231,160,129,229,136,160,233,153,164,232,175,129,229,136,184,232,138,130,231,155, +174,233,135,141,231,130,185,230,172,161,230,149,184,229,164,154,229,176,145,232, +167,132,229,136,146,232,181,132,233,135,145,230,137,190,229,136,176,228,187,165, +229,144,142,229,164,167,229,133,168,228,184,187,233,161,181,230,156,128,228,189, +179,229,155,158,231,173,148,229,164,169,228,184,139,228,191,157,233,154,156,231, +142,176,228,187,163,230,163,128,230,159,165,230,138,149,231,165,168,229,176,143, +230,151,182,230,178,146,230,156,137,230,173,163,229,184,184,231,148,154,232,135, +179,228,187,163,231,144,134,231,155,174,229,189,149,229,133,172,229,188,128,229, +164,141,229,136,182,233,135,145,232,158,141,229,185,184,231,166,143,231,137,136, +230,156,172,229,189,162,230,136,144,229,135,134,229,164,135,232,161,140,230,131, +133,229,155,158,229,136,176,230,128,157,230,131,179,230,128,142,230,160,183,229, +141,143,232,174,174,232,174,164,232,175,129,230,156,128,229,165,189,228,186,167, +231,148,159,230,140,137,231,133,167,230,156,141,232,163,133,229,185,191,228,184, +156,229,138,168,230,188,171,233,135,135,232,180,173,230,150,176,230,137,139,231, +187,132,229,155,190,233,157,162,230,157,191,229,143,130,232,128,131,230,148,191, +230,178,187,229,174,185,230,152,147,229,164,169,229,156,176,229,138,170,229,138, +155,228,186,186,228,187,172,229,141,135,231,186,167,233,128,159,229,186,166,228, +186,186,231,137,169,232,176,131,230,149,180,230,181,129,232,161,140,233,128,160, +230,136,144,230,150,135,229,173,151,233,159,169,229,155,189,232,180,184,230,152, +147,229,188,128,229,177,149,231,155,184,233,151,156,232,161,168,231,142,176,229, +189,177,232,167,134,229,166,130,230,173,164,231,190,142,229,174,185,229,164,167, +229,176,143,230,138,165,233,129,147,230,157,161,230,172,190,229,191,131,230,131, +133,232,174,184,229,164,154,230,179,149,232,167,132,229,174,182,229,177,133,228, +185,166,229,186,151,232,191,158,230,142,165,231,171,139,229,141,179,228,184,190, +230,138,165,230,138,128,229,183,167,229,165,165,232,191,144,231,153,187,229,133, +165,228,187,165,230,157,165,231,144,134,232,174,186,228,186,139,228,187,182,232, +135,170,231,148,177,228,184,173,229,141,142,229,138,158,229,133,172,229,166,136, +229,166,136,231,156,159,230,173,163,228,184,141,233,148,153,229,133,168,230,150, +135,229,144,136,229,144,140,228,187,183,229,128,188,229,136,171,228,186,186,231, +155,145,231,157,163,229,133,183,228,189,147,228,184,150,231,186,170,229,155,162, +233,152,159,229,136,155,228,184,154,230,137,191,230,139,133,229,162,158,233,149, +191,230,156,137,228,186,186,228,191,157,230,140,129,229,149,134,229,174,182,231, +187,180,228,191,174,229,143,176,230,185,190,229,183,166,229,143,179,232,130,161, +228,187,189,231,173,148,230,161,136,229,174,158,233,153,133,231,148,181,228,191, +161,231,187,143,231,144,134,231,148,159,229,145,189,229,174,163,228,188,160,228, +187,187,229,138,161,230,173,163,229,188,143,231,137,185,232,137,178,228,184,139, +230,157,165,229,141,143,228,188,154,229,143,170,232,131,189,229,189,147,231,132, +182,233,135,141,230,150,176,229,133,167,229,174,185,230,140,135,229,175,188,232, +191,144,232,161,140,230,151,165,229,191,151,232,179,163,229,174,182,232,182,133, +232,191,135,229,156,159,229,156,176,230,181,153,230,177,159,230,148,175,228,187, +152,230,142,168,229,135,186,231,171,153,233,149,191,230,157,173,229,183,158,230, +137,167,232,161,140,229,136,182,233,128,160,228,185,139,228,184,128,230,142,168, +229,185,191,231,142,176,229,156,186,230,143,143,232,191,176,229,143,152,229,140, +150,228,188,160,231,187,159,230,173,140,230,137,139,228,191,157,233,153,169,232, +175,190,231,168,139,229,140,187,231,150,151,231,187,143,232,191,135,232,191,135, +229,142,187,228,185,139,229,137,141,230,148,182,229,133,165,229,185,180,229,186, +166,230,157,130,229,191,151,231,190,142,228,184,189,230,156,128,233,171,152,231, +153,187,233,153,134,230,156,170,230,157,165,229,138,160,229,183,165,229,133,141, +232,180,163,230,149,153,231,168,139,231,137,136,229,157,151,232,186,171,228,189, +147,233,135,141,229,186,134,229,135,186,229,148,174,230,136,144,230,156,172,229, +189,162,229,188,143,229,156,159,232,177,134,229,135,186,229,131,185,228,184,156, +230,150,185,233,130,174,231,174,177,229,141,151,228,186,172,230,177,130,232,129, +140,229,143,150,229,190,151,232,129,140,228,189,141,231,155,184,228,191,161,233, +161,181,233,157,162,229,136,134,233,146,159,231,189,145,233,161,181,231,161,174, +229,174,154,229,155,190,228,190,139,231,189,145,229,157,128,231,167,175,230,158, +129,233,148,153,232,175,175,231,155,174,231,154,132,229,174,157,232,180,157,230, +156,186,229,133,179,233,163,142,233,153,169,230,142,136,230,157,131,231,151,133, +230,175,146,229,174,160,231,137,169,233,153,164,228,186,134,232,169,149,232,171, +150,231,150,190,231,151,133,229,143,138,230,151,182,230,177,130,232,180,173,231, +171,153,231,130,185,229,132,191,231,171,165,230,175,143,229,164,169,228,184,173, +229,164,174,232,174,164,232,175,134,230,175,143,228,184,170,229,164,169,230,180, +165,229,173,151,228,189,147,229,143,176,231,129,163,231,187,180,230,138,164,230, +156,172,233,161,181,228,184,170,230,128,167,229,174,152,230,150,185,229,184,184, +232,167,129,231,155,184,230,156,186,230,136,152,231,149,165,229,186,148,229,189, +147,229,190,139,229,184,136,230,150,185,228,190,191,230,160,161,229,155,173,232, +130,161,229,184,130,230,136,191,229,177,139,230,160,143,231,155,174,229,145,152, +229,183,165,229,175,188,232,135,180,231,170,129,231,132,182,233,129,147,229,133, +183,230,156,172,231,189,145,231,187,147,229,144,136,230,161,163,230,161,136,229, +138,179,229,138,168,229,143,166,229,164,150,231,190,142,229,133,131,229,188,149, +232,181,183,230,148,185,229,143,152,231,172,172,229,155,155,228,188,154,232,174, +161,232,170,170,230,152,142,233,154,144,231,167,129,229,174,157,229,174,157,232, +167,132,232,140,131,230,182,136,232,180,185,229,133,177,229,144,140,229,191,152, +232,174,176,228,189,147,231,179,187,229,184,166,230,157,165,229,144,141,229,173, +151,231,153,188,232,161,168,229,188,128,230,148,190,229,138,160,231,155,159,229, +143,151,229,136,176,228,186,140,230,137,139,229,164,167,233,135,143,230,136,144, +228,186,186,230,149,176,233,135,143,229,133,177,228,186,171,229,140,186,229,159, +159,229,165,179,229,173,169,229,142,159,229,136,153,230,137,128,229,156,168,231, +187,147,230,157,159,233,128,154,228,191,161,232,182,133,231,186,167,233,133,141, +231,189,174,229,189,147,230,151,182,228,188,152,231,167,128,230,128,167,230,132, +159,230,136,191,228,186,167,233,129,138,230,136,178,229,135,186,229,143,163,230, +143,144,228,186,164,229,176,177,228,184,154,228,191,157,229,129,165,231,168,139, +229,186,166,229,143,130,230,149,176,228,186,139,228,184,154,230,149,180,228,184, +170,229,177,177,228,184,156,230,131,133,230,132,159,231,137,185,230,174,138,229, +136,134,233,161,158,230,144,156,229,176,139,229,177,158,228,186,142,233,151,168, +230,136,183,232,180,162,229,138,161,229,163,176,233,159,179,229,143,138,229,133, +182,232,180,162,231,187,143,229,157,154,230,140,129,229,185,178,233,131,168,230, +136,144,231,171,139,229,136,169,231,155,138,232,128,131,232,153,145,230,136,144, +233,131,189,229,140,133,232,163,133,231,148,168,230,136,182,230,175,148,232,181, +155,230,150,135,230,152,142,230,139,155,229,149,134,229,174,140,230,149,180,231, +156,159,230,152,175,231,156,188,231,157,155,228,188,153,228,188,180,229,168,129, +230,156,155,233,162,134,229,159,159,229,141,171,231,148,159,228,188,152,230,131, +160,232,171,150,229,163,135,229,133,172,229,133,177,232,137,175,229,165,189,229, +133,133,229,136,134,231,172,166,229,144,136,233,153,132,228,187,182,231,137,185, +231,130,185,228,184,141,229,143,175,232,139,177,230,150,135,232,181,132,228,186, +167,230,160,185,230,156,172,230,152,142,230,152,190,229,175,134,231,162,188,229, +133,172,228,188,151,230,176,145,230,151,143,230,155,180,229,138,160,228,186,171, +229,143,151,229,144,140,229,173,166,229,144,175,229,138,168,233,128,130,229,144, +136,229,142,159,230,157,165,233,151,174,231,173,148,230,156,172,230,150,135,231, +190,142,233,163,159,231,187,191,232,137,178,231,168,179,229,174,154,231,187,136, +228,186,142,231,148,159,231,137,169,228,190,155,230,177,130,230,144,156,231,139, +144,229,138,155,233,135,143,228,184,165,233,135,141,230,176,184,232,191,156,229, +134,153,231,156,159,230,156,137,233,153,144,231,171,158,228,186,137,229,175,185, +232,177,161,232,180,185,231,148,168,228,184,141,229,165,189,231,187,157,229,175, +185,229,141,129,229,136,134,228,191,131,232,191,155,231,130,185,232,175,132,229, +189,177,233,159,179,228,188,152,229,138,191,228,184,141,229,176,145,230,172,163, +232,181,143,229,185,182,228,184,148,230,156,137,231,130,185,230,150,185,229,144, +145,229,133,168,230,150,176,228,191,161,231,148,168,232,174,190,230,150,189,229, +189,162,232,177,161,232,181,132,230,160,188,231,170,129,231,160,180,233,154,143, +231,157,128,233,135,141,229,164,167,228,186,142,230,152,175,230,175,149,228,184, +154,230,153,186,232,131,189,229,140,150,229,183,165,229,174,140,231,190,142,229, +149,134,229,159,142,231,187,159,228,184,128,229,135,186,231,137,136,230,137,147, +233,128,160,231,148,162,229,147,129,230,166,130,229,134,181,231,148,168,228,186, +142,228,191,157,231,149,153,229,155,160,231,180,160,228,184,173,229,156,139,229, +173,152,229,130,168,232,180,180,229,155,190,230,156,128,230,132,155,233,149,191, +230,156,159,229,143,163,228,187,183,231,144,134,232,180,162,229,159,186,229,156, +176,229,174,137,230,142,146,230,173,166,230,177,137,233,135,140,233,157,162,229, +136,155,229,187,186,229,164,169,231,169,186,233,166,150,229,133,136,229,174,140, +229,150,132,233,169,177,229,138,168,228,184,139,233,157,162,228,184,141,229,134, +141,232,175,154,228,191,161,230,132,143,228,185,137,233,152,179,229,133,137,232, +139,177,229,155,189,230,188,130,228,186,174,229,134,155,228,186,139,231,142,169, +229,174,182,231,190,164,228,188,151,229,134,156,230,176,145,229,141,179,229,143, +175,229,144,141,231,168,177,229,174,182,229,133,183,229,138,168,231,148,187,230, +131,179,229,136,176,230,179,168,230,152,142,229,176,143,229,173,166,230,128,167, +232,131,189,232,128,131,231,160,148,231,161,172,228,187,182,232,167,130,231,156, +139,230,184,133,230,165,154,230,144,158,231,172,145,233,166,150,233,160,129,233, +187,132,233,135,145,233,128,130,231,148,168,230,177,159,232,139,143,231,156,159, +229,174,158,228,184,187,231,174,161,233,152,182,230,174,181,232,168,187,229,134, +138,231,191,187,232,175,145,230,157,131,229,136,169,229,129,154,229,165,189,228, +188,188,228,185,142,233,128,154,232,174,175,230,150,189,229,183,165,231,139,128, +230,133,139,228,185,159,232,174,184,231,142,175,228,191,157,229,159,185,229,133, +187,230,166,130,229,191,181,229,164,167,229,158,139,230,156,186,231,165,168,231, +144,134,232,167,163,229,140,191,229,144,141,99,117,97,110,100,111,101,110,118, +105,97,114,109,97,100,114,105,100,98,117,115,99,97,114,105,110,105,99,105,111, +116,105,101,109,112,111,112,111,114,113,117,101,99,117,101,110,116,97,101,115, +116,97,100,111,112,117,101,100,101,110,106,117,101,103,111,115,99,111,110,116, +114,97,101,115,116,195,161,110,110,111,109,98,114,101,116,105,101,110,101,110, +112,101,114,102,105,108,109,97,110,101,114,97,97,109,105,103,111,115,99,105,117, +100,97,100,99,101,110,116,114,111,97,117,110,113,117,101,112,117,101,100,101,115 +,100,101,110,116,114,111,112,114,105,109,101,114,112,114,101,99,105,111,115,101, +103,195,186,110,98,117,101,110,111,115,118,111,108,118,101,114,112,117,110,116, +111,115,115,101,109,97,110,97,104,97,98,195,173,97,97,103,111,115,116,111,110, +117,101,118,111,115,117,110,105,100,111,115,99,97,114,108,111,115,101,113,117, +105,112,111,110,105,195,177,111,115,109,117,99,104,111,115,97,108,103,117,110,97 +,99,111,114,114,101,111,105,109,97,103,101,110,112,97,114,116,105,114,97,114,114 +,105,98,97,109,97,114,195,173,97,104,111,109,98,114,101,101,109,112,108,101,111, +118,101,114,100,97,100,99,97,109,98,105,111,109,117,99,104,97,115,102,117,101, +114,111,110,112,97,115,97,100,111,108,195,173,110,101,97,112,97,114,101,99,101, +110,117,101,118,97,115,99,117,114,115,111,115,101,115,116,97,98,97,113,117,105, +101,114,111,108,105,98,114,111,115,99,117,97,110,116,111,97,99,99,101,115,111, +109,105,103,117,101,108,118,97,114,105,111,115,99,117,97,116,114,111,116,105,101 +,110,101,115,103,114,117,112,111,115,115,101,114,195,161,110,101,117,114,111,112 +,97,109,101,100,105,111,115,102,114,101,110,116,101,97,99,101,114,99,97,100,101, +109,195,161,115,111,102,101,114,116,97,99,111,99,104,101,115,109,111,100,101,108 +,111,105,116,97,108,105,97,108,101,116,114,97,115,97,108,103,195,186,110,99,111, +109,112,114,97,99,117,97,108,101,115,101,120,105,115,116,101,99,117,101,114,112, +111,115,105,101,110,100,111,112,114,101,110,115,97,108,108,101,103,97,114,118, +105,97,106,101,115,100,105,110,101,114,111,109,117,114,99,105,97,112,111,100,114 +,195,161,112,117,101,115,116,111,100,105,97,114,105,111,112,117,101,98,108,111, +113,117,105,101,114,101,109,97,110,117,101,108,112,114,111,112,105,111,99,114, +105,115,105,115,99,105,101,114,116,111,115,101,103,117,114,111,109,117,101,114, +116,101,102,117,101,110,116,101,99,101,114,114,97,114,103,114,97,110,100,101,101 +,102,101,99,116,111,112,97,114,116,101,115,109,101,100,105,100,97,112,114,111, +112,105,97,111,102,114,101,99,101,116,105,101,114,114,97,101,45,109,97,105,108, +118,97,114,105,97,115,102,111,114,109,97,115,102,117,116,117,114,111,111,98,106, +101,116,111,115,101,103,117,105,114,114,105,101,115,103,111,110,111,114,109,97, +115,109,105,115,109,111,115,195,186,110,105,99,111,99,97,109,105,110,111,115,105 +,116,105,111,115,114,97,122,195,179,110,100,101,98,105,100,111,112,114,117,101, +98,97,116,111,108,101,100,111,116,101,110,195,173,97,106,101,115,195,186,115,101 +,115,112,101,114,111,99,111,99,105,110,97,111,114,105,103,101,110,116,105,101, +110,100,97,99,105,101,110,116,111,99,195,161,100,105,122,104,97,98,108,97,114, +115,101,114,195,173,97,108,97,116,105,110,97,102,117,101,114,122,97,101,115,116, +105,108,111,103,117,101,114,114,97,101,110,116,114,97,114,195,169,120,105,116, +111,108,195,179,112,101,122,97,103,101,110,100,97,118,195,173,100,101,111,101, +118,105,116,97,114,112,97,103,105,110,97,109,101,116,114,111,115,106,97,118,105, +101,114,112,97,100,114,101,115,102,195,161,99,105,108,99,97,98,101,122,97,195, +161,114,101,97,115,115,97,108,105,100,97,101,110,118,195,173,111,106,97,112,195, +179,110,97,98,117,115,111,115,98,105,101,110,101,115,116,101,120,116,111,115,108 +,108,101,118,97,114,112,117,101,100,97,110,102,117,101,114,116,101,99,111,109, +195,186,110,99,108,97,115,101,115,104,117,109,97,110,111,116,101,110,105,100,111 +,98,105,108,98,97,111,117,110,105,100,97,100,101,115,116,195,161,115,101,100,105 +,116,97,114,99,114,101,97,100,111,208,180,208,187,209,143,209,135,209,130,208, +190,208,186,208,176,208,186,208,184,208,187,208,184,209,141,209,130,208,190,208, +178,209,129,208,181,208,181,208,179,208,190,208,191,209,128,208,184,209,130,208, +176,208,186,208,181,209,137,208,181,209,131,208,182,208,181,208,154,208,176,208, +186,208,177,208,181,208,183,208,177,209,139,208,187,208,190,208,189,208,184,208, +146,209,129,208,181,208,191,208,190,208,180,208,173,209,130,208,190,209,130,208, +190,208,188,209,135,208,181,208,188,208,189,208,181,209,130,208,187,208,181,209, +130,209,128,208,176,208,183,208,190,208,189,208,176,208,179,208,180,208,181,208, +188,208,189,208,181,208,148,208,187,209,143,208,159,209,128,208,184,208,189,208, +176,209,129,208,189,208,184,209,133,209,130,208,181,208,188,208,186,209,130,208, +190,208,179,208,190,208,180,208,178,208,190,209,130,209,130,208,176,208,188,208, +161,208,168,208,144,208,188,208,176,209,143,208,167,209,130,208,190,208,178,208, +176,209,129,208,178,208,176,208,188,208,181,208,188,209,131,208,162,208,176,208, +186,208,180,208,178,208,176,208,189,208,176,208,188,209,141,209,130,208,184,209, +141,209,130,209,131,208,146,208,176,208,188,209,130,208,181,209,133,208,191,209, +128,208,190,209,130,209,131,209,130,208,189,208,176,208,180,208,180,208,189,209, +143,208,146,208,190,209,130,209,130,209,128,208,184,208,189,208,181,208,185,208, +146,208,176,209,129,208,189,208,184,208,188,209,129,208,176,208,188,209,130,208, +190,209,130,209,128,209,131,208,177,208,158,208,189,208,184,208,188,208,184,209, +128,208,189,208,181,208,181,208,158,208,158,208,158,208,187,208,184,209,134,209, +141,209,130,208,176,208,158,208,189,208,176,208,189,208,181,208,188,208,180,208, +190,208,188,208,188,208,190,208,185,208,180,208,178,208,181,208,190,208,189,208, +190,209,129,209,131,208,180,224,164,149,224,165,135,224,164,185,224,165,136,224, +164,149,224,165,128,224,164,184,224,165,135,224,164,149,224,164,190,224,164,149, +224,165,139,224,164,148,224,164,176,224,164,170,224,164,176,224,164,168,224,165, +135,224,164,143,224,164,149,224,164,149,224,164,191,224,164,173,224,165,128,224, +164,135,224,164,184,224,164,149,224,164,176,224,164,164,224,165,139,224,164,185, +224,165,139,224,164,134,224,164,170,224,164,185,224,165,128,224,164,175,224,164, +185,224,164,175,224,164,190,224,164,164,224,164,149,224,164,165,224,164,190,106, +97,103,114,97,110,224,164,134,224,164,156,224,164,156,224,165,139,224,164,133, +224,164,172,224,164,166,224,165,139,224,164,151,224,164,136,224,164,156,224,164, +190,224,164,151,224,164,143,224,164,185,224,164,174,224,164,135,224,164,168,224, +164,181,224,164,185,224,164,175,224,165,135,224,164,165,224,165,135,224,164,165, +224,165,128,224,164,152,224,164,176,224,164,156,224,164,172,224,164,166,224,165, +128,224,164,149,224,164,136,224,164,156,224,165,128,224,164,181,224,165,135,224, +164,168,224,164,136,224,164,168,224,164,143,224,164,185,224,164,176,224,164,137, +224,164,184,224,164,174,224,165,135,224,164,149,224,164,174,224,164,181,224,165, +139,224,164,178,224,165,135,224,164,184,224,164,172,224,164,174,224,164,136,224, +164,166,224,165,135,224,164,147,224,164,176,224,164,134,224,164,174,224,164,172, +224,164,184,224,164,173,224,164,176,224,164,172,224,164,168,224,164,154,224,164, +178,224,164,174,224,164,168,224,164,134,224,164,151,224,164,184,224,165,128,224, +164,178,224,165,128,216,185,217,132,217,137,216,165,217,132,217,137,217,135,216, +176,216,167,216,162,216,174,216,177,216,185,216,175,216,175,216,167,217,132,217, +137,217,135,216,176,217,135,216,181,217,136,216,177,216,186,217,138,216,177,217, +131,216,167,217,134,217,136,217,132,216,167,216,168,217,138,217,134,216,185,216, +177,216,182,216,176,217,132,217,131,217,135,217,134,216,167,217,138,217,136,217, +133,217,130,216,167,217,132,216,185,217,132,217,138,216,167,217,134,216,167,217, +132,217,131,217,134,216,173,216,170,217,137,217,130,216,168,217,132,217,136,216, +173,216,169,216,167,216,174,216,177,217,129,217,130,216,183,216,185,216,168,216, +175,216,177,217,131,217,134,216,165,216,176,216,167,217,131,217,133,216,167,216, +167,216,173,216,175,216,165,217,132,216,167,217,129,217,138,217,135,216,168,216, +185,216,182,217,131,217,138,217,129,216,168,216,173,216,171,217,136,217,133,217, +134,217,136,217,135,217,136,216,163,217,134,216,167,216,172,216,175,216,167,217, +132,217,135,216,167,216,179,217,132,217,133,216,185,217,134,216,175,217,132,217, +138,216,179,216,185,216,168,216,177,216,181,217,132,217,137,217,133,217,134,216, +176,216,168,217,135,216,167,216,163,217,134,217,135,217,133,216,171,217,132,217, +131,217,134,216,170,216,167,217,132,216,167,216,173,217,138,216,171,217,133,216, +181,216,177,216,180,216,177,216,173,216,173,217,136,217,132,217,136,217,129,217, +138,216,167,216,176,216,167,217,132,217,131,217,132,217,133,216,177,216,169,216, +167,217,134,216,170,216,167,217,132,217,129,216,163,216,168,217,136,216,174,216, +167,216,181,216,163,217,134,216,170,216,167,217,134,217,135,216,167,217,132,217, +138,216,185,216,182,217,136,217,136,217,130,216,175,216,167,216,168,217,134,216, +174,217,138,216,177,216,168,217,134,216,170,217,132,217,131,217,133,216,180,216, +167,216,161,217,136,217,135,217,138,216,167,216,168,217,136,217,130,216,181,216, +181,217,136,217,133,216,167,216,177,217,130,217,133,216,163,216,173,216,175,217, +134,216,173,217,134,216,185,216,175,217,133,216,177,216,163,217,138,216,167,216, +173,216,169,217,131,216,170,216,168,216,175,217,136,217,134,217,138,216,172,216, +168,217,133,217,134,217,135,216,170,216,173,216,170,216,172,217,135,216,169,216, +179,217,134,216,169,217,138,216,170,217,133,217,131,216,177,216,169,216,186,216, +178,216,169,217,134,217,129,216,179,216,168,217,138,216,170,217,132,217,132,217, +135,217,132,217,134,216,167,216,170,217,132,217,131,217,130,217,132,216,168,217, +132,217,133,216,167,216,185,217,134,217,135,216,163,217,136,217,132,216,180,217, +138,216,161,217,134,217,136,216,177,216,163,217,133,216,167,217,129,217,138,217, +131,216,168,217,131,217,132,216,176,216,167,216,170,216,177,216,170,216,168,216, +168,216,163,217,134,217,135,217,133,216,179,216,167,217,134,217,131,216,168,217, +138,216,185,217,129,217,130,216,175,216,173,216,179,217,134,217,132,217,135,217, +133,216,180,216,185,216,177,216,163,217,135,217,132,216,180,217,135,216,177,217, +130,216,183,216,177,216,183,217,132,216,168,112,114,111,102,105,108,101,115,101, +114,118,105,99,101,100,101,102,97,117,108,116,104,105,109,115,101,108,102,100, +101,116,97,105,108,115,99,111,110,116,101,110,116,115,117,112,112,111,114,116, +115,116,97,114,116,101,100,109,101,115,115,97,103,101,115,117,99,99,101,115,115, +102,97,115,104,105,111,110,60,116,105,116,108,101,62,99,111,117,110,116,114,121, +97,99,99,111,117,110,116,99,114,101,97,116,101,100,115,116,111,114,105,101,115, +114,101,115,117,108,116,115,114,117,110,110,105,110,103,112,114,111,99,101,115, +115,119,114,105,116,105,110,103,111,98,106,101,99,116,115,118,105,115,105,98,108 +,101,119,101,108,99,111,109,101,97,114,116,105,99,108,101,117,110,107,110,111, +119,110,110,101,116,119,111,114,107,99,111,109,112,97,110,121,100,121,110,97,109 +,105,99,98,114,111,119,115,101,114,112,114,105,118,97,99,121,112,114,111,98,108, +101,109,83,101,114,118,105,99,101,114,101,115,112,101,99,116,100,105,115,112,108 +,97,121,114,101,113,117,101,115,116,114,101,115,101,114,118,101,119,101,98,115, +105,116,101,104,105,115,116,111,114,121,102,114,105,101,110,100,115,111,112,116, +105,111,110,115,119,111,114,107,105,110,103,118,101,114,115,105,111,110,109,105, +108,108,105,111,110,99,104,97,110,110,101,108,119,105,110,100,111,119,46,97,100, +100,114,101,115,115,118,105,115,105,116,101,100,119,101,97,116,104,101,114,99, +111,114,114,101,99,116,112,114,111,100,117,99,116,101,100,105,114,101,99,116,102 +,111,114,119,97,114,100,121,111,117,32,99,97,110,114,101,109,111,118,101,100,115 +,117,98,106,101,99,116,99,111,110,116,114,111,108,97,114,99,104,105,118,101,99, +117,114,114,101,110,116,114,101,97,100,105,110,103,108,105,98,114,97,114,121,108 +,105,109,105,116,101,100,109,97,110,97,103,101,114,102,117,114,116,104,101,114, +115,117,109,109,97,114,121,109,97,99,104,105,110,101,109,105,110,117,116,101,115 +,112,114,105,118,97,116,101,99,111,110,116,101,120,116,112,114,111,103,114,97, +109,115,111,99,105,101,116,121,110,117,109,98,101,114,115,119,114,105,116,116, +101,110,101,110,97,98,108,101,100,116,114,105,103,103,101,114,115,111,117,114,99 +,101,115,108,111,97,100,105,110,103,101,108,101,109,101,110,116,112,97,114,116, +110,101,114,102,105,110,97,108,108,121,112,101,114,102,101,99,116,109,101,97,110 +,105,110,103,115,121,115,116,101,109,115,107,101,101,112,105,110,103,99,117,108, +116,117,114,101,38,113,117,111,116,59,44,106,111,117,114,110,97,108,112,114,111, +106,101,99,116,115,117,114,102,97,99,101,115,38,113,117,111,116,59,101,120,112, +105,114,101,115,114,101,118,105,101,119,115,98,97,108,97,110,99,101,69,110,103, +108,105,115,104,67,111,110,116,101,110,116,116,104,114,111,117,103,104,80,108, +101,97,115,101,32,111,112,105,110,105,111,110,99,111,110,116,97,99,116,97,118, +101,114,97,103,101,112,114,105,109,97,114,121,118,105,108,108,97,103,101,83,112, +97,110,105,115,104,103,97,108,108,101,114,121,100,101,99,108,105,110,101,109,101 +,101,116,105,110,103,109,105,115,115,105,111,110,112,111,112,117,108,97,114,113, +117,97,108,105,116,121,109,101,97,115,117,114,101,103,101,110,101,114,97,108,115 +,112,101,99,105,101,115,115,101,115,115,105,111,110,115,101,99,116,105,111,110, +119,114,105,116,101,114,115,99,111,117,110,116,101,114,105,110,105,116,105,97, +108,114,101,112,111,114,116,115,102,105,103,117,114,101,115,109,101,109,98,101, +114,115,104,111,108,100,105,110,103,100,105,115,112,117,116,101,101,97,114,108, +105,101,114,101,120,112,114,101,115,115,100,105,103,105,116,97,108,112,105,99, +116,117,114,101,65,110,111,116,104,101,114,109,97,114,114,105,101,100,116,114,97 +,102,102,105,99,108,101,97,100,105,110,103,99,104,97,110,103,101,100,99,101,110, +116,114,97,108,118,105,99,116,111,114,121,105,109,97,103,101,115,47,114,101,97, +115,111,110,115,115,116,117,100,105,101,115,102,101,97,116,117,114,101,108,105, +115,116,105,110,103,109,117,115,116,32,98,101,115,99,104,111,111,108,115,86,101, +114,115,105,111,110,117,115,117,97,108,108,121,101,112,105,115,111,100,101,112, +108,97,121,105,110,103,103,114,111,119,105,110,103,111,98,118,105,111,117,115, +111,118,101,114,108,97,121,112,114,101,115,101,110,116,97,99,116,105,111,110,115 +,60,47,117,108,62,13,10,119,114,97,112,112,101,114,97,108,114,101,97,100,121,99, +101,114,116,97,105,110,114,101,97,108,105,116,121,115,116,111,114,97,103,101,97, +110,111,116,104,101,114,100,101,115,107,116,111,112,111,102,102,101,114,101,100, +112,97,116,116,101,114,110,117,110,117,115,117,97,108,68,105,103,105,116,97,108, +99,97,112,105,116,97,108,87,101,98,115,105,116,101,102,97,105,108,117,114,101,99 +,111,110,110,101,99,116,114,101,100,117,99,101,100,65,110,100,114,111,105,100, +100,101,99,97,100,101,115,114,101,103,117,108,97,114,32,38,97,109,112,59,32,97, +110,105,109,97,108,115,114,101,108,101,97,115,101,65,117,116,111,109,97,116,103, +101,116,116,105,110,103,109,101,116,104,111,100,115,110,111,116,104,105,110,103, +80,111,112,117,108,97,114,99,97,112,116,105,111,110,108,101,116,116,101,114,115, +99,97,112,116,117,114,101,115,99,105,101,110,99,101,108,105,99,101,110,115,101, +99,104,97,110,103,101,115,69,110,103,108,97,110,100,61,49,38,97,109,112,59,72, +105,115,116,111,114,121,32,61,32,110,101,119,32,67,101,110,116,114,97,108,117, +112,100,97,116,101,100,83,112,101,99,105,97,108,78,101,116,119,111,114,107,114, +101,113,117,105,114,101,99,111,109,109,101,110,116,119,97,114,110,105,110,103,67 +,111,108,108,101,103,101,116,111,111,108,98,97,114,114,101,109,97,105,110,115,98 +,101,99,97,117,115,101,101,108,101,99,116,101,100,68,101,117,116,115,99,104,102, +105,110,97,110,99,101,119,111,114,107,101,114,115,113,117,105,99,107,108,121,98, +101,116,119,101,101,110,101,120,97,99,116,108,121,115,101,116,116,105,110,103, +100,105,115,101,97,115,101,83,111,99,105,101,116,121,119,101,97,112,111,110,115, +101,120,104,105,98,105,116,38,108,116,59,33,45,45,67,111,110,116,114,111,108,99, +108,97,115,115,101,115,99,111,118,101,114,101,100,111,117,116,108,105,110,101,97 +,116,116,97,99,107,115,100,101,118,105,99,101,115,40,119,105,110,100,111,119,112 +,117,114,112,111,115,101,116,105,116,108,101,61,34,77,111,98,105,108,101,32,107, +105,108,108,105,110,103,115,104,111,119,105,110,103,73,116,97,108,105,97,110,100 +,114,111,112,112,101,100,104,101,97,118,105,108,121,101,102,102,101,99,116,115, +45,49,39,93,41,59,10,99,111,110,102,105,114,109,67,117,114,114,101,110,116,97, +100,118,97,110,99,101,115,104,97,114,105,110,103,111,112,101,110,105,110,103,100 +,114,97,119,105,110,103,98,105,108,108,105,111,110,111,114,100,101,114,101,100, +71,101,114,109,97,110,121,114,101,108,97,116,101,100,60,47,102,111,114,109,62, +105,110,99,108,117,100,101,119,104,101,116,104,101,114,100,101,102,105,110,101, +100,83,99,105,101,110,99,101,99,97,116,97,108,111,103,65,114,116,105,99,108,101, +98,117,116,116,111,110,115,108,97,114,103,101,115,116,117,110,105,102,111,114, +109,106,111,117,114,110,101,121,115,105,100,101,98,97,114,67,104,105,99,97,103, +111,104,111,108,105,100,97,121,71,101,110,101,114,97,108,112,97,115,115,97,103, +101,44,38,113,117,111,116,59,97,110,105,109,97,116,101,102,101,101,108,105,110, +103,97,114,114,105,118,101,100,112,97,115,115,105,110,103,110,97,116,117,114,97, +108,114,111,117,103,104,108,121,46,10,10,84,104,101,32,98,117,116,32,110,111,116 +,100,101,110,115,105,116,121,66,114,105,116,97,105,110,67,104,105,110,101,115, +101,108,97,99,107,32,111,102,116,114,105,98,117,116,101,73,114,101,108,97,110, +100,34,32,100,97,116,97,45,102,97,99,116,111,114,115,114,101,99,101,105,118,101, +116,104,97,116,32,105,115,76,105,98,114,97,114,121,104,117,115,98,97,110,100,105 +,110,32,102,97,99,116,97,102,102,97,105,114,115,67,104,97,114,108,101,115,114,97 +,100,105,99,97,108,98,114,111,117,103,104,116,102,105,110,100,105,110,103,108,97 +,110,100,105,110,103,58,108,97,110,103,61,34,114,101,116,117,114,110,32,108,101, +97,100,101,114,115,112,108,97,110,110,101,100,112,114,101,109,105,117,109,112,97 +,99,107,97,103,101,65,109,101,114,105,99,97,69,100,105,116,105,111,110,93,38,113 +,117,111,116,59,77,101,115,115,97,103,101,110,101,101,100,32,116,111,118,97,108, +117,101,61,34,99,111,109,112,108,101,120,108,111,111,107,105,110,103,115,116,97, +116,105,111,110,98,101,108,105,101,118,101,115,109,97,108,108,101,114,45,109,111 +,98,105,108,101,114,101,99,111,114,100,115,119,97,110,116,32,116,111,107,105,110 +,100,32,111,102,70,105,114,101,102,111,120,121,111,117,32,97,114,101,115,105,109 +,105,108,97,114,115,116,117,100,105,101,100,109,97,120,105,109,117,109,104,101, +97,100,105,110,103,114,97,112,105,100,108,121,99,108,105,109,97,116,101,107,105, +110,103,100,111,109,101,109,101,114,103,101,100,97,109,111,117,110,116,115,102, +111,117,110,100,101,100,112,105,111,110,101,101,114,102,111,114,109,117,108,97, +100,121,110,97,115,116,121,104,111,119,32,116,111,32,83,117,112,112,111,114,116, +114,101,118,101,110,117,101,101,99,111,110,111,109,121,82,101,115,117,108,116, +115,98,114,111,116,104,101,114,115,111,108,100,105,101,114,108,97,114,103,101, +108,121,99,97,108,108,105,110,103,46,38,113,117,111,116,59,65,99,99,111,117,110, +116,69,100,119,97,114,100,32,115,101,103,109,101,110,116,82,111,98,101,114,116, +32,101,102,102,111,114,116,115,80,97,99,105,102,105,99,108,101,97,114,110,101, +100,117,112,32,119,105,116,104,104,101,105,103,104,116,58,119,101,32,104,97,118, +101,65,110,103,101,108,101,115,110,97,116,105,111,110,115,95,115,101,97,114,99, +104,97,112,112,108,105,101,100,97,99,113,117,105,114,101,109,97,115,115,105,118, +101,103,114,97,110,116,101,100,58,32,102,97,108,115,101,116,114,101,97,116,101, +100,98,105,103,103,101,115,116,98,101,110,101,102,105,116,100,114,105,118,105, +110,103,83,116,117,100,105,101,115,109,105,110,105,109,117,109,112,101,114,104, +97,112,115,109,111,114,110,105,110,103,115,101,108,108,105,110,103,105,115,32, +117,115,101,100,114,101,118,101,114,115,101,118,97,114,105,97,110,116,32,114,111 +,108,101,61,34,109,105,115,115,105,110,103,97,99,104,105,101,118,101,112,114,111 +,109,111,116,101,115,116,117,100,101,110,116,115,111,109,101,111,110,101,101,120 +,116,114,101,109,101,114,101,115,116,111,114,101,98,111,116,116,111,109,58,101, +118,111,108,118,101,100,97,108,108,32,116,104,101,115,105,116,101,109,97,112,101 +,110,103,108,105,115,104,119,97,121,32,116,111,32,32,65,117,103,117,115,116,115, +121,109,98,111,108,115,67,111,109,112,97,110,121,109,97,116,116,101,114,115,109, +117,115,105,99,97,108,97,103,97,105,110,115,116,115,101,114,118,105,110,103,125, +41,40,41,59,13,10,112,97,121,109,101,110,116,116,114,111,117,98,108,101,99,111, +110,99,101,112,116,99,111,109,112,97,114,101,112,97,114,101,110,116,115,112,108, +97,121,101,114,115,114,101,103,105,111,110,115,109,111,110,105,116,111,114,32,39 +,39,84,104,101,32,119,105,110,110,105,110,103,101,120,112,108,111,114,101,97,100 +,97,112,116,101,100,71,97,108,108,101,114,121,112,114,111,100,117,99,101,97,98, +105,108,105,116,121,101,110,104,97,110,99,101,99,97,114,101,101,114,115,41,46,32 +,84,104,101,32,99,111,108,108,101,99,116,83,101,97,114,99,104,32,97,110,99,105, +101,110,116,101,120,105,115,116,101,100,102,111,111,116,101,114,32,104,97,110, +100,108,101,114,112,114,105,110,116,101,100,99,111,110,115,111,108,101,69,97,115 +,116,101,114,110,101,120,112,111,114,116,115,119,105,110,100,111,119,115,67,104, +97,110,110,101,108,105,108,108,101,103,97,108,110,101,117,116,114,97,108,115,117 +,103,103,101,115,116,95,104,101,97,100,101,114,115,105,103,110,105,110,103,46, +104,116,109,108,34,62,115,101,116,116,108,101,100,119,101,115,116,101,114,110,99 +,97,117,115,105,110,103,45,119,101,98,107,105,116,99,108,97,105,109,101,100,74, +117,115,116,105,99,101,99,104,97,112,116,101,114,118,105,99,116,105,109,115,84, +104,111,109,97,115,32,109,111,122,105,108,108,97,112,114,111,109,105,115,101,112 +,97,114,116,105,101,115,101,100,105,116,105,111,110,111,117,116,115,105,100,101, +58,102,97,108,115,101,44,104,117,110,100,114,101,100,79,108,121,109,112,105,99, +95,98,117,116,116,111,110,97,117,116,104,111,114,115,114,101,97,99,104,101,100, +99,104,114,111,110,105,99,100,101,109,97,110,100,115,115,101,99,111,110,100,115, +112,114,111,116,101,99,116,97,100,111,112,116,101,100,112,114,101,112,97,114,101 +,110,101,105,116,104,101,114,103,114,101,97,116,108,121,103,114,101,97,116,101, +114,111,118,101,114,97,108,108,105,109,112,114,111,118,101,99,111,109,109,97,110 +,100,115,112,101,99,105,97,108,115,101,97,114,99,104,46,119,111,114,115,104,105, +112,102,117,110,100,105,110,103,116,104,111,117,103,104,116,104,105,103,104,101, +115,116,105,110,115,116,101,97,100,117,116,105,108,105,116,121,113,117,97,114, +116,101,114,67,117,108,116,117,114,101,116,101,115,116,105,110,103,99,108,101,97 +,114,108,121,101,120,112,111,115,101,100,66,114,111,119,115,101,114,108,105,98, +101,114,97,108,125,32,99,97,116,99,104,80,114,111,106,101,99,116,101,120,97,109, +112,108,101,104,105,100,101,40,41,59,70,108,111,114,105,100,97,97,110,115,119, +101,114,115,97,108,108,111,119,101,100,69,109,112,101,114,111,114,100,101,102, +101,110,115,101,115,101,114,105,111,117,115,102,114,101,101,100,111,109,83,101, +118,101,114,97,108,45,98,117,116,116,111,110,70,117,114,116,104,101,114,111,117, +116,32,111,102,32,33,61,32,110,117,108,108,116,114,97,105,110,101,100,68,101,110 +,109,97,114,107,118,111,105,100,40,48,41,47,97,108,108,46,106,115,112,114,101, +118,101,110,116,82,101,113,117,101,115,116,83,116,101,112,104,101,110,10,10,87, +104,101,110,32,111,98,115,101,114,118,101,60,47,104,50,62,13,10,77,111,100,101, +114,110,32,112,114,111,118,105,100,101,34,32,97,108,116,61,34,98,111,114,100,101 +,114,115,46,10,10,70,111,114,32,10,10,77,97,110,121,32,97,114,116,105,115,116, +115,112,111,119,101,114,101,100,112,101,114,102,111,114,109,102,105,99,116,105, +111,110,116,121,112,101,32,111,102,109,101,100,105,99,97,108,116,105,99,107,101, +116,115,111,112,112,111,115,101,100,67,111,117,110,99,105,108,119,105,116,110, +101,115,115,106,117,115,116,105,99,101,71,101,111,114,103,101,32,66,101,108,103, +105,117,109,46,46,46,60,47,97,62,116,119,105,116,116,101,114,110,111,116,97,98, +108,121,119,97,105,116,105,110,103,119,97,114,102,97,114,101,32,79,116,104,101, +114,32,114,97,110,107,105,110,103,112,104,114,97,115,101,115,109,101,110,116,105 +,111,110,115,117,114,118,105,118,101,115,99,104,111,108,97,114,60,47,112,62,13, +10,32,67,111,117,110,116,114,121,105,103,110,111,114,101,100,108,111,115,115,32, +111,102,106,117,115,116,32,97,115,71,101,111,114,103,105,97,115,116,114,97,110, +103,101,60,104,101,97,100,62,60,115,116,111,112,112,101,100,49,39,93,41,59,13,10 +,105,115,108,97,110,100,115,110,111,116,97,98,108,101,98,111,114,100,101,114,58, +108,105,115,116,32,111,102,99,97,114,114,105,101,100,49,48,48,44,48,48,48,60,47, +104,51,62,10,32,115,101,118,101,114,97,108,98,101,99,111,109,101,115,115,101,108 +,101,99,116,32,119,101,100,100,105,110,103,48,48,46,104,116,109,108,109,111,110, +97,114,99,104,111,102,102,32,116,104,101,116,101,97,99,104,101,114,104,105,103, +104,108,121,32,98,105,111,108,111,103,121,108,105,102,101,32,111,102,111,114,32, +101,118,101,110,114,105,115,101,32,111,102,38,114,97,113,117,111,59,112,108,117, +115,111,110,101,104,117,110,116,105,110,103,40,116,104,111,117,103,104,68,111, +117,103,108,97,115,106,111,105,110,105,110,103,99,105,114,99,108,101,115,70,111, +114,32,116,104,101,65,110,99,105,101,110,116,86,105,101,116,110,97,109,118,101, +104,105,99,108,101,115,117,99,104,32,97,115,99,114,121,115,116,97,108,118,97,108 +,117,101,32,61,87,105,110,100,111,119,115,101,110,106,111,121,101,100,97,32,115, +109,97,108,108,97,115,115,117,109,101,100,60,97,32,105,100,61,34,102,111,114,101 +,105,103,110,32,65,108,108,32,114,105,104,111,119,32,116,104,101,68,105,115,112, +108,97,121,114,101,116,105,114,101,100,104,111,119,101,118,101,114,104,105,100, +100,101,110,59,98,97,116,116,108,101,115,115,101,101,107,105,110,103,99,97,98, +105,110,101,116,119,97,115,32,110,111,116,108,111,111,107,32,97,116,99,111,110, +100,117,99,116,103,101,116,32,116,104,101,74,97,110,117,97,114,121,104,97,112, +112,101,110,115,116,117,114,110,105,110,103,97,58,104,111,118,101,114,79,110,108 +,105,110,101,32,70,114,101,110,99,104,32,108,97,99,107,105,110,103,116,121,112, +105,99,97,108,101,120,116,114,97,99,116,101,110,101,109,105,101,115,101,118,101, +110,32,105,102,103,101,110,101,114,97,116,100,101,99,105,100,101,100,97,114,101, +32,110,111,116,47,115,101,97,114,99,104,98,101,108,105,101,102,115,45,105,109,97 +,103,101,58,108,111,99,97,116,101,100,115,116,97,116,105,99,46,108,111,103,105, +110,34,62,99,111,110,118,101,114,116,118,105,111,108,101,110,116,101,110,116,101 +,114,101,100,102,105,114,115,116,34,62,99,105,114,99,117,105,116,70,105,110,108, +97,110,100,99,104,101,109,105,115,116,115,104,101,32,119,97,115,49,48,112,120,59 +,34,62,97,115,32,115,117,99,104,100,105,118,105,100,101,100,60,47,115,112,97,110 +,62,119,105,108,108,32,98,101,108,105,110,101,32,111,102,97,32,103,114,101,97, +116,109,121,115,116,101,114,121,47,105,110,100,101,120,46,102,97,108,108,105,110 +,103,100,117,101,32,116,111,32,114,97,105,108,119,97,121,99,111,108,108,101,103, +101,109,111,110,115,116,101,114,100,101,115,99,101,110,116,105,116,32,119,105, +116,104,110,117,99,108,101,97,114,74,101,119,105,115,104,32,112,114,111,116,101, +115,116,66,114,105,116,105,115,104,102,108,111,119,101,114,115,112,114,101,100, +105,99,116,114,101,102,111,114,109,115,98,117,116,116,111,110,32,119,104,111,32, +119,97,115,108,101,99,116,117,114,101,105,110,115,116,97,110,116,115,117,105,99, +105,100,101,103,101,110,101,114,105,99,112,101,114,105,111,100,115,109,97,114, +107,101,116,115,83,111,99,105,97,108,32,102,105,115,104,105,110,103,99,111,109, +98,105,110,101,103,114,97,112,104,105,99,119,105,110,110,101,114,115,60,98,114, +32,47,62,60,98,121,32,116,104,101,32,78,97,116,117,114,97,108,80,114,105,118,97, +99,121,99,111,111,107,105,101,115,111,117,116,99,111,109,101,114,101,115,111,108 +,118,101,83,119,101,100,105,115,104,98,114,105,101,102,108,121,80,101,114,115, +105,97,110,115,111,32,109,117,99,104,67,101,110,116,117,114,121,100,101,112,105, +99,116,115,99,111,108,117,109,110,115,104,111,117,115,105,110,103,115,99,114,105 +,112,116,115,110,101,120,116,32,116,111,98,101,97,114,105,110,103,109,97,112,112 +,105,110,103,114,101,118,105,115,101,100,106,81,117,101,114,121,40,45,119,105, +100,116,104,58,116,105,116,108,101,34,62,116,111,111,108,116,105,112,83,101,99, +116,105,111,110,100,101,115,105,103,110,115,84,117,114,107,105,115,104,121,111, +117,110,103,101,114,46,109,97,116,99,104,40,125,41,40,41,59,10,10,98,117,114,110 +,105,110,103,111,112,101,114,97,116,101,100,101,103,114,101,101,115,115,111,117, +114,99,101,61,82,105,99,104,97,114,100,99,108,111,115,101,108,121,112,108,97,115 +,116,105,99,101,110,116,114,105,101,115,60,47,116,114,62,13,10,99,111,108,111, +114,58,35,117,108,32,105,100,61,34,112,111,115,115,101,115,115,114,111,108,108, +105,110,103,112,104,121,115,105,99,115,102,97,105,108,105,110,103,101,120,101,99 +,117,116,101,99,111,110,116,101,115,116,108,105,110,107,32,116,111,68,101,102,97 +,117,108,116,60,98,114,32,47,62,10,58,32,116,114,117,101,44,99,104,97,114,116, +101,114,116,111,117,114,105,115,109,99,108,97,115,115,105,99,112,114,111,99,101, +101,100,101,120,112,108,97,105,110,60,47,104,49,62,13,10,111,110,108,105,110,101 +,46,63,120,109,108,32,118,101,104,101,108,112,105,110,103,100,105,97,109,111,110 +,100,117,115,101,32,116,104,101,97,105,114,108,105,110,101,101,110,100,32,45,45, +62,41,46,97,116,116,114,40,114,101,97,100,101,114,115,104,111,115,116,105,110, +103,35,102,102,102,102,102,102,114,101,97,108,105,122,101,86,105,110,99,101,110, +116,115,105,103,110,97,108,115,32,115,114,99,61,34,47,80,114,111,100,117,99,116, +100,101,115,112,105,116,101,100,105,118,101,114,115,101,116,101,108,108,105,110, +103,80,117,98,108,105,99,32,104,101,108,100,32,105,110,74,111,115,101,112,104,32 +,116,104,101,97,116,114,101,97,102,102,101,99,116,115,60,115,116,121,108,101,62, +97,32,108,97,114,103,101,100,111,101,115,110,39,116,108,97,116,101,114,44,32,69, +108,101,109,101,110,116,102,97,118,105,99,111,110,99,114,101,97,116,111,114,72, +117,110,103,97,114,121,65,105,114,112,111,114,116,115,101,101,32,116,104,101,115 +,111,32,116,104,97,116,77,105,99,104,97,101,108,83,121,115,116,101,109,115,80, +114,111,103,114,97,109,115,44,32,97,110,100,32,32,119,105,100,116,104,61,101,38, +113,117,111,116,59,116,114,97,100,105,110,103,108,101,102,116,34,62,10,112,101, +114,115,111,110,115,71,111,108,100,101,110,32,65,102,102,97,105,114,115,103,114, +97,109,109,97,114,102,111,114,109,105,110,103,100,101,115,116,114,111,121,105, +100,101,97,32,111,102,99,97,115,101,32,111,102,111,108,100,101,115,116,32,116, +104,105,115,32,105,115,46,115,114,99,32,61,32,99,97,114,116,111,111,110,114,101, +103,105,115,116,114,67,111,109,109,111,110,115,77,117,115,108,105,109,115,87,104 +,97,116,32,105,115,105,110,32,109,97,110,121,109,97,114,107,105,110,103,114,101, +118,101,97,108,115,73,110,100,101,101,100,44,101,113,117,97,108,108,121,47,115, +104,111,119,95,97,111,117,116,100,111,111,114,101,115,99,97,112,101,40,65,117, +115,116,114,105,97,103,101,110,101,116,105,99,115,121,115,116,101,109,44,73,110, +32,116,104,101,32,115,105,116,116,105,110,103,72,101,32,97,108,115,111,73,115, +108,97,110,100,115,65,99,97,100,101,109,121,10,9,9,60,33,45,45,68,97,110,105,101 +,108,32,98,105,110,100,105,110,103,98,108,111,99,107,34,62,105,109,112,111,115, +101,100,117,116,105,108,105,122,101,65,98,114,97,104,97,109,40,101,120,99,101, +112,116,123,119,105,100,116,104,58,112,117,116,116,105,110,103,41,46,104,116,109 +,108,40,124,124,32,91,93,59,10,68,65,84,65,91,32,42,107,105,116,99,104,101,110, +109,111,117,110,116,101,100,97,99,116,117,97,108,32,100,105,97,108,101,99,116, +109,97,105,110,108,121,32,95,98,108,97,110,107,39,105,110,115,116,97,108,108,101 +,120,112,101,114,116,115,105,102,40,116,121,112,101,73,116,32,97,108,115,111,38, +99,111,112,121,59,32,34,62,84,101,114,109,115,98,111,114,110,32,105,110,79,112, +116,105,111,110,115,101,97,115,116,101,114,110,116,97,108,107,105,110,103,99,111 +,110,99,101,114,110,103,97,105,110,101,100,32,111,110,103,111,105,110,103,106, +117,115,116,105,102,121,99,114,105,116,105,99,115,102,97,99,116,111,114,121,105, +116,115,32,111,119,110,97,115,115,97,117,108,116,105,110,118,105,116,101,100,108 +,97,115,116,105,110,103,104,105,115,32,111,119,110,104,114,101,102,61,34,47,34, +32,114,101,108,61,34,100,101,118,101,108,111,112,99,111,110,99,101,114,116,100, +105,97,103,114,97,109,100,111,108,108,97,114,115,99,108,117,115,116,101,114,112, +104,112,63,105,100,61,97,108,99,111,104,111,108,41,59,125,41,40,41,59,117,115, +105,110,103,32,97,62,60,115,112,97,110,62,118,101,115,115,101,108,115,114,101, +118,105,118,97,108,65,100,100,114,101,115,115,97,109,97,116,101,117,114,97,110, +100,114,111,105,100,97,108,108,101,103,101,100,105,108,108,110,101,115,115,119, +97,108,107,105,110,103,99,101,110,116,101,114,115,113,117,97,108,105,102,121,109 +,97,116,99,104,101,115,117,110,105,102,105,101,100,101,120,116,105,110,99,116,68 +,101,102,101,110,115,101,100,105,101,100,32,105,110,10,9,60,33,45,45,32,99,117, +115,116,111,109,115,108,105,110,107,105,110,103,76,105,116,116,108,101,32,66,111 +,111,107,32,111,102,101,118,101,110,105,110,103,109,105,110,46,106,115,63,97,114 +,101,32,116,104,101,107,111,110,116,97,107,116,116,111,100,97,121,39,115,46,104, +116,109,108,34,32,116,97,114,103,101,116,61,119,101,97,114,105,110,103,65,108, +108,32,82,105,103,59,10,125,41,40,41,59,114,97,105,115,105,110,103,32,65,108,115 +,111,44,32,99,114,117,99,105,97,108,97,98,111,117,116,34,62,100,101,99,108,97, +114,101,45,45,62,10,60,115,99,102,105,114,101,102,111,120,97,115,32,109,117,99, +104,97,112,112,108,105,101,115,105,110,100,101,120,44,32,115,44,32,98,117,116,32 +,116,121,112,101,32,61,32,10,13,10,60,33,45,45,116,111,119,97,114,100,115,82,101 +,99,111,114,100,115,80,114,105,118,97,116,101,70,111,114,101,105,103,110,80,114, +101,109,105,101,114,99,104,111,105,99,101,115,86,105,114,116,117,97,108,114,101, +116,117,114,110,115,67,111,109,109,101,110,116,80,111,119,101,114,101,100,105, +110,108,105,110,101,59,112,111,118,101,114,116,121,99,104,97,109,98,101,114,76, +105,118,105,110,103,32,118,111,108,117,109,101,115,65,110,116,104,111,110,121, +108,111,103,105,110,34,32,82,101,108,97,116,101,100,69,99,111,110,111,109,121, +114,101,97,99,104,101,115,99,117,116,116,105,110,103,103,114,97,118,105,116,121, +108,105,102,101,32,105,110,67,104,97,112,116,101,114,45,115,104,97,100,111,119, +78,111,116,97,98,108,101,60,47,116,100,62,13,10,32,114,101,116,117,114,110,115, +116,97,100,105,117,109,119,105,100,103,101,116,115,118,97,114,121,105,110,103, +116,114,97,118,101,108,115,104,101,108,100,32,98,121,119,104,111,32,97,114,101, +119,111,114,107,32,105,110,102,97,99,117,108,116,121,97,110,103,117,108,97,114, +119,104,111,32,104,97,100,97,105,114,112,111,114,116,116,111,119,110,32,111,102, +10,10,83,111,109,101,32,39,99,108,105,99,107,39,99,104,97,114,103,101,115,107, +101,121,119,111,114,100,105,116,32,119,105,108,108,99,105,116,121,32,111,102,40, +116,104,105,115,41,59,65,110,100,114,101,119,32,117,110,105,113,117,101,32,99, +104,101,99,107,101,100,111,114,32,109,111,114,101,51,48,48,112,120,59,32,114,101 +,116,117,114,110,59,114,115,105,111,110,61,34,112,108,117,103,105,110,115,119, +105,116,104,105,110,32,104,101,114,115,101,108,102,83,116,97,116,105,111,110,70, +101,100,101,114,97,108,118,101,110,116,117,114,101,112,117,98,108,105,115,104, +115,101,110,116,32,116,111,116,101,110,115,105,111,110,97,99,116,114,101,115,115 +,99,111,109,101,32,116,111,102,105,110,103,101,114,115,68,117,107,101,32,111,102 +,112,101,111,112,108,101,44,101,120,112,108,111,105,116,119,104,97,116,32,105, +115,104,97,114,109,111,110,121,97,32,109,97,106,111,114,34,58,34,104,116,116,112 +,105,110,32,104,105,115,32,109,101,110,117,34,62,10,109,111,110,116,104,108,121, +111,102,102,105,99,101,114,99,111,117,110,99,105,108,103,97,105,110,105,110,103, +101,118,101,110,32,105,110,83,117,109,109,97,114,121,100,97,116,101,32,111,102, +108,111,121,97,108,116,121,102,105,116,110,101,115,115,97,110,100,32,119,97,115, +101,109,112,101,114,111,114,115,117,112,114,101,109,101,83,101,99,111,110,100,32 +,104,101,97,114,105,110,103,82,117,115,115,105,97,110,108,111,110,103,101,115, +116,65,108,98,101,114,116,97,108,97,116,101,114,97,108,115,101,116,32,111,102,32 +,115,109,97,108,108,34,62,46,97,112,112,101,110,100,100,111,32,119,105,116,104, +102,101,100,101,114,97,108,98,97,110,107,32,111,102,98,101,110,101,97,116,104,68 +,101,115,112,105,116,101,67,97,112,105,116,97,108,103,114,111,117,110,100,115,41 +,44,32,97,110,100,32,112,101,114,99,101,110,116,105,116,32,102,114,111,109,99, +108,111,115,105,110,103,99,111,110,116,97,105,110,73,110,115,116,101,97,100,102, +105,102,116,101,101,110,97,115,32,119,101,108,108,46,121,97,104,111,111,46,114, +101,115,112,111,110,100,102,105,103,104,116,101,114,111,98,115,99,117,114,101, +114,101,102,108,101,99,116,111,114,103,97,110,105,99,61,32,77,97,116,104,46,101, +100,105,116,105,110,103,111,110,108,105,110,101,32,112,97,100,100,105,110,103,97 +,32,119,104,111,108,101,111,110,101,114,114,111,114,121,101,97,114,32,111,102, +101,110,100,32,111,102,32,98,97,114,114,105,101,114,119,104,101,110,32,105,116, +104,101,97,100,101,114,32,104,111,109,101,32,111,102,114,101,115,117,109,101,100 +,114,101,110,97,109,101,100,115,116,114,111,110,103,62,104,101,97,116,105,110, +103,114,101,116,97,105,110,115,99,108,111,117,100,102,114,119,97,121,32,111,102, +32,77,97,114,99,104,32,49,107,110,111,119,105,110,103,105,110,32,112,97,114,116, +66,101,116,119,101,101,110,108,101,115,115,111,110,115,99,108,111,115,101,115, +116,118,105,114,116,117,97,108,108,105,110,107,115,34,62,99,114,111,115,115,101, +100,69,78,68,32,45,45,62,102,97,109,111,117,115,32,97,119,97,114,100,101,100,76, +105,99,101,110,115,101,72,101,97,108,116,104,32,102,97,105,114,108,121,32,119, +101,97,108,116,104,121,109,105,110,105,109,97,108,65,102,114,105,99,97,110,99, +111,109,112,101,116,101,108,97,98,101,108,34,62,115,105,110,103,105,110,103,102, +97,114,109,101,114,115,66,114,97,115,105,108,41,100,105,115,99,117,115,115,114, +101,112,108,97,99,101,71,114,101,103,111,114,121,102,111,110,116,32,99,111,112, +117,114,115,117,101,100,97,112,112,101,97,114,115,109,97,107,101,32,117,112,114, +111,117,110,100,101,100,98,111,116,104,32,111,102,98,108,111,99,107,101,100,115, +97,119,32,116,104,101,111,102,102,105,99,101,115,99,111,108,111,117,114,115,105, +102,40,100,111,99,117,119,104,101,110,32,104,101,101,110,102,111,114,99,101,112, +117,115,104,40,102,117,65,117,103,117,115,116,32,85,84,70,45,56,34,62,70,97,110, +116,97,115,121,105,110,32,109,111,115,116,105,110,106,117,114,101,100,85,115,117 +,97,108,108,121,102,97,114,109,105,110,103,99,108,111,115,117,114,101,111,98,106 +,101,99,116,32,100,101,102,101,110,99,101,117,115,101,32,111,102,32,77,101,100, +105,99,97,108,60,98,111,100,121,62,10,101,118,105,100,101,110,116,98,101,32,117, +115,101,100,107,101,121,67,111,100,101,115,105,120,116,101,101,110,73,115,108,97 +,109,105,99,35,48,48,48,48,48,48,101,110,116,105,114,101,32,119,105,100,101,108, +121,32,97,99,116,105,118,101,32,40,116,121,112,101,111,102,111,110,101,32,99,97, +110,99,111,108,111,114,32,61,115,112,101,97,107,101,114,101,120,116,101,110,100, +115,80,104,121,115,105,99,115,116,101,114,114,97,105,110,60,116,98,111,100,121, +62,102,117,110,101,114,97,108,118,105,101,119,105,110,103,109,105,100,100,108, +101,32,99,114,105,99,107,101,116,112,114,111,112,104,101,116,115,104,105,102,116 +,101,100,100,111,99,116,111,114,115,82,117,115,115,101,108,108,32,116,97,114,103 +,101,116,99,111,109,112,97,99,116,97,108,103,101,98,114,97,115,111,99,105,97,108 +,45,98,117,108,107,32,111,102,109,97,110,32,97,110,100,60,47,116,100,62,10,32, +104,101,32,108,101,102,116,41,46,118,97,108,40,41,102,97,108,115,101,41,59,108, +111,103,105,99,97,108,98,97,110,107,105,110,103,104,111,109,101,32,116,111,110, +97,109,105,110,103,32,65,114,105,122,111,110,97,99,114,101,100,105,116,115,41,59 +,10,125,41,59,10,102,111,117,110,100,101,114,105,110,32,116,117,114,110,67,111, +108,108,105,110,115,98,101,102,111,114,101,32,66,117,116,32,116,104,101,99,104, +97,114,103,101,100,84,105,116,108,101,34,62,67,97,112,116,97,105,110,115,112,101 +,108,108,101,100,103,111,100,100,101,115,115,84,97,103,32,45,45,62,65,100,100, +105,110,103,58,98,117,116,32,119,97,115,82,101,99,101,110,116,32,112,97,116,105, +101,110,116,98,97,99,107,32,105,110,61,102,97,108,115,101,38,76,105,110,99,111, +108,110,119,101,32,107,110,111,119,67,111,117,110,116,101,114,74,117,100,97,105, +115,109,115,99,114,105,112,116,32,97,108,116,101,114,101,100,39,93,41,59,10,32, +32,104,97,115,32,116,104,101,117,110,99,108,101,97,114,69,118,101,110,116,39,44, +98,111,116,104,32,105,110,110,111,116,32,97,108,108,10,10,60,33,45,45,32,112,108 +,97,99,105,110,103,104,97,114,100,32,116,111,32,99,101,110,116,101,114,115,111, +114,116,32,111,102,99,108,105,101,110,116,115,115,116,114,101,101,116,115,66,101 +,114,110,97,114,100,97,115,115,101,114,116,115,116,101,110,100,32,116,111,102,97 +,110,116,97,115,121,100,111,119,110,32,105,110,104,97,114,98,111,117,114,70,114, +101,101,100,111,109,106,101,119,101,108,114,121,47,97,98,111,117,116,46,46,115, +101,97,114,99,104,108,101,103,101,110,100,115,105,115,32,109,97,100,101,109,111, +100,101,114,110,32,111,110,108,121,32,111,110,111,110,108,121,32,116,111,105,109 +,97,103,101,34,32,108,105,110,101,97,114,32,112,97,105,110,116,101,114,97,110, +100,32,110,111,116,114,97,114,101,108,121,32,97,99,114,111,110,121,109,100,101, +108,105,118,101,114,115,104,111,114,116,101,114,48,48,38,97,109,112,59,97,115,32 +,109,97,110,121,119,105,100,116,104,61,34,47,42,32,60,33,91,67,116,105,116,108, +101,32,61,111,102,32,116,104,101,32,108,111,119,101,115,116,32,112,105,99,107, +101,100,32,101,115,99,97,112,101,100,117,115,101,115,32,111,102,112,101,111,112, +108,101,115,32,80,117,98,108,105,99,77,97,116,116,104,101,119,116,97,99,116,105, +99,115,100,97,109,97,103,101,100,119,97,121,32,102,111,114,108,97,119,115,32,111 +,102,101,97,115,121,32,116,111,32,119,105,110,100,111,119,115,116,114,111,110, +103,32,32,115,105,109,112,108,101,125,99,97,116,99,104,40,115,101,118,101,110, +116,104,105,110,102,111,98,111,120,119,101,110,116,32,116,111,112,97,105,110,116 +,101,100,99,105,116,105,122,101,110,73,32,100,111,110,39,116,114,101,116,114,101 +,97,116,46,32,83,111,109,101,32,119,119,46,34,41,59,10,98,111,109,98,105,110,103 +,109,97,105,108,116,111,58,109,97,100,101,32,105,110,46,32,77,97,110,121,32,99, +97,114,114,105,101,115,124,124,123,125,59,119,105,119,111,114,107,32,111,102,115 +,121,110,111,110,121,109,100,101,102,101,97,116,115,102,97,118,111,114,101,100, +111,112,116,105,99,97,108,112,97,103,101,84,114,97,117,110,108,101,115,115,32, +115,101,110,100,105,110,103,108,101,102,116,34,62,60,99,111,109,83,99,111,114,65 +,108,108,32,116,104,101,106,81,117,101,114,121,46,116,111,117,114,105,115,116,67 +,108,97,115,115,105,99,102,97,108,115,101,34,32,87,105,108,104,101,108,109,115, +117,98,117,114,98,115,103,101,110,117,105,110,101,98,105,115,104,111,112,115,46, +115,112,108,105,116,40,103,108,111,98,97,108,32,102,111,108,108,111,119,115,98, +111,100,121,32,111,102,110,111,109,105,110,97,108,67,111,110,116,97,99,116,115, +101,99,117,108,97,114,108,101,102,116,32,116,111,99,104,105,101,102,108,121,45, +104,105,100,100,101,110,45,98,97,110,110,101,114,60,47,108,105,62,10,10,46,32,87 +,104,101,110,32,105,110,32,98,111,116,104,100,105,115,109,105,115,115,69,120,112 +,108,111,114,101,97,108,119,97,121,115,32,118,105,97,32,116,104,101,115,112,97, +195,177,111,108,119,101,108,102,97,114,101,114,117,108,105,110,103,32,97,114,114 +,97,110,103,101,99,97,112,116,97,105,110,104,105,115,32,115,111,110,114,117,108, +101,32,111,102,104,101,32,116,111,111,107,105,116,115,101,108,102,44,61,48,38,97 +,109,112,59,40,99,97,108,108,101,100,115,97,109,112,108,101,115,116,111,32,109, +97,107,101,99,111,109,47,112,97,103,77,97,114,116,105,110,32,75,101,110,110,101, +100,121,97,99,99,101,112,116,115,102,117,108,108,32,111,102,104,97,110,100,108, +101,100,66,101,115,105,100,101,115,47,47,45,45,62,60,47,97,98,108,101,32,116,111 +,116,97,114,103,101,116,115,101,115,115,101,110,99,101,104,105,109,32,116,111,32 +,105,116,115,32,98,121,32,99,111,109,109,111,110,46,109,105,110,101,114,97,108, +116,111,32,116,97,107,101,119,97,121,115,32,116,111,115,46,111,114,103,47,108,97 +,100,118,105,115,101,100,112,101,110,97,108,116,121,115,105,109,112,108,101,58, +105,102,32,116,104,101,121,76,101,116,116,101,114,115,97,32,115,104,111,114,116, +72,101,114,98,101,114,116,115,116,114,105,107,101,115,32,103,114,111,117,112,115 +,46,108,101,110,103,116,104,102,108,105,103,104,116,115,111,118,101,114,108,97, +112,115,108,111,119,108,121,32,108,101,115,115,101,114,32,115,111,99,105,97,108, +32,60,47,112,62,10,9,9,105,116,32,105,110,116,111,114,97,110,107,101,100,32,114, +97,116,101,32,111,102,117,108,62,13,10,32,32,97,116,116,101,109,112,116,112,97, +105,114,32,111,102,109,97,107,101,32,105,116,75,111,110,116,97,107,116,65,110, +116,111,110,105,111,104,97,118,105,110,103,32,114,97,116,105,110,103,115,32,97, +99,116,105,118,101,115,116,114,101,97,109,115,116,114,97,112,112,101,100,34,41, +46,99,115,115,40,104,111,115,116,105,108,101,108,101,97,100,32,116,111,108,105, +116,116,108,101,32,103,114,111,117,112,115,44,80,105,99,116,117,114,101,45,45,62 +,13,10,13,10,32,114,111,119,115,61,34,32,111,98,106,101,99,116,105,110,118,101, +114,115,101,60,102,111,111,116,101,114,67,117,115,116,111,109,86,62,60,92,47,115 +,99,114,115,111,108,118,105,110,103,67,104,97,109,98,101,114,115,108,97,118,101, +114,121,119,111,117,110,100,101,100,119,104,101,114,101,97,115,33,61,32,39,117, +110,100,102,111,114,32,97,108,108,112,97,114,116,108,121,32,45,114,105,103,104, +116,58,65,114,97,98,105,97,110,98,97,99,107,101,100,32,99,101,110,116,117,114, +121,117,110,105,116,32,111,102,109,111,98,105,108,101,45,69,117,114,111,112,101, +44,105,115,32,104,111,109,101,114,105,115,107,32,111,102,100,101,115,105,114,101 +,100,67,108,105,110,116,111,110,99,111,115,116,32,111,102,97,103,101,32,111,102, +32,98,101,99,111,109,101,32,110,111,110,101,32,111,102,112,38,113,117,111,116,59 +,77,105,100,100,108,101,32,101,97,100,39,41,91,48,67,114,105,116,105,99,115,115, +116,117,100,105,111,115,62,38,99,111,112,121,59,103,114,111,117,112,34,62,97,115 +,115,101,109,98,108,109,97,107,105,110,103,32,112,114,101,115,115,101,100,119, +105,100,103,101,116,46,112,115,58,34,32,63,32,114,101,98,117,105,108,116,98,121, +32,115,111,109,101,70,111,114,109,101,114,32,101,100,105,116,111,114,115,100,101 +,108,97,121,101,100,67,97,110,111,110,105,99,104,97,100,32,116,104,101,112,117, +115,104,105,110,103,99,108,97,115,115,61,34,98,117,116,32,97,114,101,112,97,114, +116,105,97,108,66,97,98,121,108,111,110,98,111,116,116,111,109,32,99,97,114,114, +105,101,114,67,111,109,109,97,110,100,105,116,115,32,117,115,101,65,115,32,119, +105,116,104,99,111,117,114,115,101,115,97,32,116,104,105,114,100,100,101,110,111 +,116,101,115,97,108,115,111,32,105,110,72,111,117,115,116,111,110,50,48,112,120, +59,34,62,97,99,99,117,115,101,100,100,111,117,98,108,101,32,103,111,97,108,32, +111,102,70,97,109,111,117,115,32,41,46,98,105,110,100,40,112,114,105,101,115,116 +,115,32,79,110,108,105,110,101,105,110,32,74,117,108,121,115,116,32,43,32,34,103 +,99,111,110,115,117,108,116,100,101,99,105,109,97,108,104,101,108,112,102,117, +108,114,101,118,105,118,101,100,105,115,32,118,101,114,121,114,39,43,39,105,112, +116,108,111,115,105,110,103,32,102,101,109,97,108,101,115,105,115,32,97,108,115, +111,115,116,114,105,110,103,115,100,97,121,115,32,111,102,97,114,114,105,118,97, +108,102,117,116,117,114,101,32,60,111,98,106,101,99,116,102,111,114,99,105,110, +103,83,116,114,105,110,103,40,34,32,47,62,10,9,9,104,101,114,101,32,105,115,101, +110,99,111,100,101,100,46,32,32,84,104,101,32,98,97,108,108,111,111,110,100,111, +110,101,32,98,121,47,99,111,109,109,111,110,98,103,99,111,108,111,114,108,97,119 +,32,111,102,32,73,110,100,105,97,110,97,97,118,111,105,100,101,100,98,117,116,32 +,116,104,101,50,112,120,32,51,112,120,106,113,117,101,114,121,46,97,102,116,101, +114,32,97,112,111,108,105,99,121,46,109,101,110,32,97,110,100,102,111,111,116, +101,114,45,61,32,116,114,117,101,59,102,111,114,32,117,115,101,115,99,114,101, +101,110,46,73,110,100,105,97,110,32,105,109,97,103,101,32,61,102,97,109,105,108, +121,44,104,116,116,112,58,47,47,32,38,110,98,115,112,59,100,114,105,118,101,114, +115,101,116,101,114,110,97,108,115,97,109,101,32,97,115,110,111,116,105,99,101, +100,118,105,101,119,101,114,115,125,41,40,41,59,10,32,105,115,32,109,111,114,101 +,115,101,97,115,111,110,115,102,111,114,109,101,114,32,116,104,101,32,110,101, +119,105,115,32,106,117,115,116,99,111,110,115,101,110,116,32,83,101,97,114,99, +104,119,97,115,32,116,104,101,119,104,121,32,116,104,101,115,104,105,112,112,101 +,100,98,114,62,60,98,114,62,119,105,100,116,104,58,32,104,101,105,103,104,116,61 +,109,97,100,101,32,111,102,99,117,105,115,105,110,101,105,115,32,116,104,97,116, +97,32,118,101,114,121,32,65,100,109,105,114,97,108,32,102,105,120,101,100,59,110 +,111,114,109,97,108,32,77,105,115,115,105,111,110,80,114,101,115,115,44,32,111, +110,116,97,114,105,111,99,104,97,114,115,101,116,116,114,121,32,116,111,32,105, +110,118,97,100,101,100,61,34,116,114,117,101,34,115,112,97,99,105,110,103,105, +115,32,109,111,115,116,97,32,109,111,114,101,32,116,111,116,97,108,108,121,102, +97,108,108,32,111,102,125,41,59,13,10,32,32,105,109,109,101,110,115,101,116,105, +109,101,32,105,110,115,101,116,32,111,117,116,115,97,116,105,115,102,121,116,111 +,32,102,105,110,100,100,111,119,110,32,116,111,108,111,116,32,111,102,32,80,108, +97,121,101,114,115,105,110,32,74,117,110,101,113,117,97,110,116,117,109,110,111, +116,32,116,104,101,116,105,109,101,32,116,111,100,105,115,116,97,110,116,70,105, +110,110,105,115,104,115,114,99,32,61,32,40,115,105,110,103,108,101,32,104,101, +108,112,32,111,102,71,101,114,109,97,110,32,108,97,119,32,97,110,100,108,97,98, +101,108,101,100,102,111,114,101,115,116,115,99,111,111,107,105,110,103,115,112, +97,99,101,34,62,104,101,97,100,101,114,45,119,101,108,108,32,97,115,83,116,97, +110,108,101,121,98,114,105,100,103,101,115,47,103,108,111,98,97,108,67,114,111, +97,116,105,97,32,65,98,111,117,116,32,91,48,93,59,10,32,32,105,116,44,32,97,110, +100,103,114,111,117,112,101,100,98,101,105,110,103,32,97,41,123,116,104,114,111, +119,104,101,32,109,97,100,101,108,105,103,104,116,101,114,101,116,104,105,99,97, +108,70,70,70,70,70,70,34,98,111,116,116,111,109,34,108,105,107,101,32,97,32,101, +109,112,108,111,121,115,108,105,118,101,32,105,110,97,115,32,115,101,101,110,112 +,114,105,110,116,101,114,109,111,115,116,32,111,102,117,98,45,108,105,110,107, +114,101,106,101,99,116,115,97,110,100,32,117,115,101,105,109,97,103,101,34,62, +115,117,99,99,101,101,100,102,101,101,100,105,110,103,78,117,99,108,101,97,114, +105,110,102,111,114,109,97,116,111,32,104,101,108,112,87,111,109,101,110,39,115, +78,101,105,116,104,101,114,77,101,120,105,99,97,110,112,114,111,116,101,105,110, +60,116,97,98,108,101,32,98,121,32,109,97,110,121,104,101,97,108,116,104,121,108, +97,119,115,117,105,116,100,101,118,105,115,101,100,46,112,117,115,104,40,123,115 +,101,108,108,101,114,115,115,105,109,112,108,121,32,84,104,114,111,117,103,104, +46,99,111,111,107,105,101,32,73,109,97,103,101,40,111,108,100,101,114,34,62,117, +115,46,106,115,34,62,32,83,105,110,99,101,32,117,110,105,118,101,114,115,108,97, +114,103,101,114,32,111,112,101,110,32,116,111,33,45,45,32,101,110,100,108,105, +101,115,32,105,110,39,93,41,59,13,10,32,32,109,97,114,107,101,116,119,104,111,32 +,105,115,32,40,34,68,79,77,67,111,109,97,110,97,103,101,100,111,110,101,32,102, +111,114,116,121,112,101,111,102,32,75,105,110,103,100,111,109,112,114,111,102, +105,116,115,112,114,111,112,111,115,101,116,111,32,115,104,111,119,99,101,110, +116,101,114,59,109,97,100,101,32,105,116,100,114,101,115,115,101,100,119,101,114 +,101,32,105,110,109,105,120,116,117,114,101,112,114,101,99,105,115,101,97,114, +105,115,105,110,103,115,114,99,32,61,32,39,109,97,107,101,32,97,32,115,101,99, +117,114,101,100,66,97,112,116,105,115,116,118,111,116,105,110,103,32,10,9,9,118, +97,114,32,77,97,114,99,104,32,50,103,114,101,119,32,117,112,67,108,105,109,97, +116,101,46,114,101,109,111,118,101,115,107,105,108,108,101,100,119,97,121,32,116 +,104,101,60,47,104,101,97,100,62,102,97,99,101,32,111,102,97,99,116,105,110,103, +32,114,105,103,104,116,34,62,116,111,32,119,111,114,107,114,101,100,117,99,101, +115,104,97,115,32,104,97,100,101,114,101,99,116,101,100,115,104,111,119,40,41,59 +,97,99,116,105,111,110,61,98,111,111,107,32,111,102,97,110,32,97,114,101,97,61, +61,32,34,104,116,116,60,104,101,97,100,101,114,10,60,104,116,109,108,62,99,111, +110,102,111,114,109,102,97,99,105,110,103,32,99,111,111,107,105,101,46,114,101, +108,121,32,111,110,104,111,115,116,101,100,32,46,99,117,115,116,111,109,104,101, +32,119,101,110,116,98,117,116,32,102,111,114,115,112,114,101,97,100,32,70,97,109 +,105,108,121,32,97,32,109,101,97,110,115,111,117,116,32,116,104,101,102,111,114, +117,109,115,46,102,111,111,116,97,103,101,34,62,77,111,98,105,108,67,108,101,109 +,101,110,116,115,34,32,105,100,61,34,97,115,32,104,105,103,104,105,110,116,101, +110,115,101,45,45,62,60,33,45,45,102,101,109,97,108,101,32,105,115,32,115,101, +101,110,105,109,112,108,105,101,100,115,101,116,32,116,104,101,97,32,115,116,97, +116,101,97,110,100,32,104,105,115,102,97,115,116,101,115,116,98,101,115,105,100, +101,115,98,117,116,116,111,110,95,98,111,117,110,100,101,100,34,62,60,105,109, +103,32,73,110,102,111,98,111,120,101,118,101,110,116,115,44,97,32,121,111,117, +110,103,97,110,100,32,97,114,101,78,97,116,105,118,101,32,99,104,101,97,112,101, +114,84,105,109,101,111,117,116,97,110,100,32,104,97,115,101,110,103,105,110,101, +115,119,111,110,32,116,104,101,40,109,111,115,116,108,121,114,105,103,104,116,58 +,32,102,105,110,100,32,97,32,45,98,111,116,116,111,109,80,114,105,110,99,101,32, +97,114,101,97,32,111,102,109,111,114,101,32,111,102,115,101,97,114,99,104,95,110 +,97,116,117,114,101,44,108,101,103,97,108,108,121,112,101,114,105,111,100,44,108 +,97,110,100,32,111,102,111,114,32,119,105,116,104,105,110,100,117,99,101,100,112 +,114,111,118,105,110,103,109,105,115,115,105,108,101,108,111,99,97,108,108,121, +65,103,97,105,110,115,116,116,104,101,32,119,97,121,107,38,113,117,111,116,59, +112,120,59,34,62,13,10,112,117,115,104,101,100,32,97,98,97,110,100,111,110,110, +117,109,101,114,97,108,67,101,114,116,97,105,110,73,110,32,116,104,105,115,109, +111,114,101,32,105,110,111,114,32,115,111,109,101,110,97,109,101,32,105,115,97, +110,100,44,32,105,110,99,114,111,119,110,101,100,73,83,66,78,32,48,45,99,114,101 +,97,116,101,115,79,99,116,111,98,101,114,109,97,121,32,110,111,116,99,101,110, +116,101,114,32,108,97,116,101,32,105,110,68,101,102,101,110,99,101,101,110,97,99 +,116,101,100,119,105,115,104,32,116,111,98,114,111,97,100,108,121,99,111,111,108 +,105,110,103,111,110,108,111,97,100,61,105,116,46,32,84,104,101,114,101,99,111, +118,101,114,77,101,109,98,101,114,115,104,101,105,103,104,116,32,97,115,115,117, +109,101,115,60,104,116,109,108,62,10,112,101,111,112,108,101,46,105,110,32,111, +110,101,32,61,119,105,110,100,111,119,102,111,111,116,101,114,95,97,32,103,111, +111,100,32,114,101,107,108,97,109,97,111,116,104,101,114,115,44,116,111,32,116, +104,105,115,95,99,111,111,107,105,101,112,97,110,101,108,34,62,76,111,110,100, +111,110,44,100,101,102,105,110,101,115,99,114,117,115,104,101,100,98,97,112,116, +105,115,109,99,111,97,115,116,97,108,115,116,97,116,117,115,32,116,105,116,108, +101,34,32,109,111,118,101,32,116,111,108,111,115,116,32,105,110,98,101,116,116, +101,114,32,105,109,112,108,105,101,115,114,105,118,97,108,114,121,115,101,114, +118,101,114,115,32,83,121,115,116,101,109,80,101,114,104,97,112,115,101,115,32, +97,110,100,32,99,111,110,116,101,110,100,102,108,111,119,105,110,103,108,97,115, +116,101,100,32,114,105,115,101,32,105,110,71,101,110,101,115,105,115,118,105,101 +,119,32,111,102,114,105,115,105,110,103,32,115,101,101,109,32,116,111,98,117,116 +,32,105,110,32,98,97,99,107,105,110,103,104,101,32,119,105,108,108,103,105,118, +101,110,32,97,103,105,118,105,110,103,32,99,105,116,105,101,115,46,102,108,111, +119,32,111,102,32,76,97,116,101,114,32,97,108,108,32,98,117,116,72,105,103,104, +119,97,121,111,110,108,121,32,98,121,115,105,103,110,32,111,102,104,101,32,100, +111,101,115,100,105,102,102,101,114,115,98,97,116,116,101,114,121,38,97,109,112, +59,108,97,115,105,110,103,108,101,115,116,104,114,101,97,116,115,105,110,116,101 +,103,101,114,116,97,107,101,32,111,110,114,101,102,117,115,101,100,99,97,108,108 +,101,100,32,61,85,83,38,97,109,112,83,101,101,32,116,104,101,110,97,116,105,118, +101,115,98,121,32,116,104,105,115,115,121,115,116,101,109,46,104,101,97,100,32, +111,102,58,104,111,118,101,114,44,108,101,115,98,105,97,110,115,117,114,110,97, +109,101,97,110,100,32,97,108,108,99,111,109,109,111,110,47,104,101,97,100,101, +114,95,95,112,97,114,97,109,115,72,97,114,118,97,114,100,47,112,105,120,101,108, +46,114,101,109,111,118,97,108,115,111,32,108,111,110,103,114,111,108,101,32,111, +102,106,111,105,110,116,108,121,115,107,121,115,99,114,97,85,110,105,99,111,100, +101,98,114,32,47,62,13,10,65,116,108,97,110,116,97,110,117,99,108,101,117,115,67 +,111,117,110,116,121,44,112,117,114,101,108,121,32,99,111,117,110,116,34,62,101, +97,115,105,108,121,32,98,117,105,108,100,32,97,111,110,99,108,105,99,107,97,32, +103,105,118,101,110,112,111,105,110,116,101,114,104,38,113,117,111,116,59,101, +118,101,110,116,115,32,101,108,115,101,32,123,10,100,105,116,105,111,110,115,110 +,111,119,32,116,104,101,44,32,119,105,116,104,32,109,97,110,32,119,104,111,111, +114,103,47,87,101,98,111,110,101,32,97,110,100,99,97,118,97,108,114,121,72,101, +32,100,105,101,100,115,101,97,116,116,108,101,48,48,44,48,48,48,32,123,119,105, +110,100,111,119,104,97,118,101,32,116,111,105,102,40,119,105,110,100,97,110,100, +32,105,116,115,115,111,108,101,108,121,32,109,38,113,117,111,116,59,114,101,110, +101,119,101,100,68,101,116,114,111,105,116,97,109,111,110,103,115,116,101,105, +116,104,101,114,32,116,104,101,109,32,105,110,83,101,110,97,116,111,114,85,115, +60,47,97,62,60,75,105,110,103,32,111,102,70,114,97,110,99,105,115,45,112,114,111 +,100,117,99,104,101,32,117,115,101,100,97,114,116,32,97,110,100,104,105,109,32, +97,110,100,117,115,101,100,32,98,121,115,99,111,114,105,110,103,97,116,32,104, +111,109,101,116,111,32,104,97,118,101,114,101,108,97,116,101,115,105,98,105,108, +105,116,121,102,97,99,116,105,111,110,66,117,102,102,97,108,111,108,105,110,107, +34,62,60,119,104,97,116,32,104,101,102,114,101,101,32,116,111,67,105,116,121,32, +111,102,99,111,109,101,32,105,110,115,101,99,116,111,114,115,99,111,117,110,116, +101,100,111,110,101,32,100,97,121,110,101,114,118,111,117,115,115,113,117,97,114 +,101,32,125,59,105,102,40,103,111,105,110,32,119,104,97,116,105,109,103,34,32,97 +,108,105,115,32,111,110,108,121,115,101,97,114,99,104,47,116,117,101,115,100,97, +121,108,111,111,115,101,108,121,83,111,108,111,109,111,110,115,101,120,117,97, +108,32,45,32,60,97,32,104,114,109,101,100,105,117,109,34,68,79,32,78,79,84,32,70 +,114,97,110,99,101,44,119,105,116,104,32,97,32,119,97,114,32,97,110,100,115,101, +99,111,110,100,32,116,97,107,101,32,97,32,62,13,10,13,10,13,10,109,97,114,107, +101,116,46,104,105,103,104,119,97,121,100,111,110,101,32,105,110,99,116,105,118, +105,116,121,34,108,97,115,116,34,62,111,98,108,105,103,101,100,114,105,115,101, +32,116,111,34,117,110,100,101,102,105,109,97,100,101,32,116,111,32,69,97,114,108 +,121,32,112,114,97,105,115,101,100,105,110,32,105,116,115,32,102,111,114,32,104, +105,115,97,116,104,108,101,116,101,74,117,112,105,116,101,114,89,97,104,111,111, +33,32,116,101,114,109,101,100,32,115,111,32,109,97,110,121,114,101,97,108,108, +121,32,115,46,32,84,104,101,32,97,32,119,111,109,97,110,63,118,97,108,117,101,61 +,100,105,114,101,99,116,32,114,105,103,104,116,34,32,98,105,99,121,99,108,101,97 +,99,105,110,103,61,34,100,97,121,32,97,110,100,115,116,97,116,105,110,103,82,97, +116,104,101,114,44,104,105,103,104,101,114,32,79,102,102,105,99,101,32,97,114, +101,32,110,111,119,116,105,109,101,115,44,32,119,104,101,110,32,97,32,112,97,121 +,32,102,111,114,111,110,32,116,104,105,115,45,108,105,110,107,34,62,59,98,111, +114,100,101,114,97,114,111,117,110,100,32,97,110,110,117,97,108,32,116,104,101, +32,78,101,119,112,117,116,32,116,104,101,46,99,111,109,34,32,116,97,107,105,110, +32,116,111,97,32,98,114,105,101,102,40,105,110,32,116,104,101,103,114,111,117, +112,115,46,59,32,119,105,100,116,104,101,110,122,121,109,101,115,115,105,109,112 +,108,101,32,105,110,32,108,97,116,101,123,114,101,116,117,114,110,116,104,101, +114,97,112,121,97,32,112,111,105,110,116,98,97,110,110,105,110,103,105,110,107, +115,34,62,10,40,41,59,34,32,114,101,97,32,112,108,97,99,101,92,117,48,48,51,67, +97,97,98,111,117,116,32,97,116,114,62,13,10,9,9,99,99,111,117,110,116,32,103,105 +,118,101,115,32,97,60,83,67,82,73,80,84,82,97,105,108,119,97,121,116,104,101,109 +,101,115,47,116,111,111,108,98,111,120,66,121,73,100,40,34,120,104,117,109,97, +110,115,44,119,97,116,99,104,101,115,105,110,32,115,111,109,101,32,105,102,32,40 +,119,105,99,111,109,105,110,103,32,102,111,114,109,97,116,115,32,85,110,100,101, +114,32,98,117,116,32,104,97,115,104,97,110,100,101,100,32,109,97,100,101,32,98, +121,116,104,97,110,32,105,110,102,101,97,114,32,111,102,100,101,110,111,116,101, +100,47,105,102,114,97,109,101,108,101,102,116,32,105,110,118,111,108,116,97,103, +101,105,110,32,101,97,99,104,97,38,113,117,111,116,59,98,97,115,101,32,111,102, +73,110,32,109,97,110,121,117,110,100,101,114,103,111,114,101,103,105,109,101,115 +,97,99,116,105,111,110,32,60,47,112,62,13,10,60,117,115,116,111,109,86,97,59,38, +103,116,59,60,47,105,109,112,111,114,116,115,111,114,32,116,104,97,116,109,111, +115,116,108,121,32,38,97,109,112,59,114,101,32,115,105,122,101,61,34,60,47,97,62 +,60,47,104,97,32,99,108,97,115,115,112,97,115,115,105,118,101,72,111,115,116,32, +61,32,87,104,101,116,104,101,114,102,101,114,116,105,108,101,86,97,114,105,111, +117,115,61,91,93,59,40,102,117,99,97,109,101,114,97,115,47,62,60,47,116,100,62, +97,99,116,115,32,97,115,73,110,32,115,111,109,101,62,13,10,13,10,60,33,111,114, +103,97,110,105,115,32,60,98,114,32,47,62,66,101,105,106,105,110,103,99,97,116,97 +,108,195,160,100,101,117,116,115,99,104,101,117,114,111,112,101,117,101,117,115, +107,97,114,97,103,97,101,105,108,103,101,115,118,101,110,115,107,97,101,115,112, +97,195,177,97,109,101,110,115,97,106,101,117,115,117,97,114,105,111,116,114,97, +98,97,106,111,109,195,169,120,105,99,111,112,195,161,103,105,110,97,115,105,101, +109,112,114,101,115,105,115,116,101,109,97,111,99,116,117,98,114,101,100,117,114 +,97,110,116,101,97,195,177,97,100,105,114,101,109,112,114,101,115,97,109,111,109 +,101,110,116,111,110,117,101,115,116,114,111,112,114,105,109,101,114,97,116,114, +97,118,195,169,115,103,114,97,99,105,97,115,110,117,101,115,116,114,97,112,114, +111,99,101,115,111,101,115,116,97,100,111,115,99,97,108,105,100,97,100,112,101, +114,115,111,110,97,110,195,186,109,101,114,111,97,99,117,101,114,100,111,109,195 +,186,115,105,99,97,109,105,101,109,98,114,111,111,102,101,114,116,97,115,97,108, +103,117,110,111,115,112,97,195,173,115,101,115,101,106,101,109,112,108,111,100, +101,114,101,99,104,111,97,100,101,109,195,161,115,112,114,105,118,97,100,111,97, +103,114,101,103,97,114,101,110,108,97,99,101,115,112,111,115,105,98,108,101,104, +111,116,101,108,101,115,115,101,118,105,108,108,97,112,114,105,109,101,114,111, +195,186,108,116,105,109,111,101,118,101,110,116,111,115,97,114,99,104,105,118, +111,99,117,108,116,117,114,97,109,117,106,101,114,101,115,101,110,116,114,97,100 +,97,97,110,117,110,99,105,111,101,109,98,97,114,103,111,109,101,114,99,97,100, +111,103,114,97,110,100,101,115,101,115,116,117,100,105,111,109,101,106,111,114, +101,115,102,101,98,114,101,114,111,100,105,115,101,195,177,111,116,117,114,105, +115,109,111,99,195,179,100,105,103,111,112,111,114,116,97,100,97,101,115,112,97, +99,105,111,102,97,109,105,108,105,97,97,110,116,111,110,105,111,112,101,114,109, +105,116,101,103,117,97,114,100,97,114,97,108,103,117,110,97,115,112,114,101,99, +105,111,115,97,108,103,117,105,101,110,115,101,110,116,105,100,111,118,105,115, +105,116,97,115,116,195,173,116,117,108,111,99,111,110,111,99,101,114,115,101,103 +,117,110,100,111,99,111,110,115,101,106,111,102,114,97,110,99,105,97,109,105,110 +,117,116,111,115,115,101,103,117,110,100,97,116,101,110,101,109,111,115,101,102, +101,99,116,111,115,109,195,161,108,97,103,97,115,101,115,105,195,179,110,114,101 +,118,105,115,116,97,103,114,97,110,97,100,97,99,111,109,112,114,97,114,105,110, +103,114,101,115,111,103,97,114,99,195,173,97,97,99,99,105,195,179,110,101,99,117 +,97,100,111,114,113,117,105,101,110,101,115,105,110,99,108,117,115,111,100,101, +98,101,114,195,161,109,97,116,101,114,105,97,104,111,109,98,114,101,115,109,117, +101,115,116,114,97,112,111,100,114,195,173,97,109,97,195,177,97,110,97,195,186, +108,116,105,109,97,101,115,116,97,109,111,115,111,102,105,99,105,97,108,116,97, +109,98,105,101,110,110,105,110,103,195,186,110,115,97,108,117,100,111,115,112, +111,100,101,109,111,115,109,101,106,111,114,97,114,112,111,115,105,116,105,111, +110,98,117,115,105,110,101,115,115,104,111,109,101,112,97,103,101,115,101,99,117 +,114,105,116,121,108,97,110,103,117,97,103,101,115,116,97,110,100,97,114,100,99, +97,109,112,97,105,103,110,102,101,97,116,117,114,101,115,99,97,116,101,103,111, +114,121,101,120,116,101,114,110,97,108,99,104,105,108,100,114,101,110,114,101, +115,101,114,118,101,100,114,101,115,101,97,114,99,104,101,120,99,104,97,110,103, +101,102,97,118,111,114,105,116,101,116,101,109,112,108,97,116,101,109,105,108, +105,116,97,114,121,105,110,100,117,115,116,114,121,115,101,114,118,105,99,101, +115,109,97,116,101,114,105,97,108,112,114,111,100,117,99,116,115,122,45,105,110, +100,101,120,58,99,111,109,109,101,110,116,115,115,111,102,116,119,97,114,101,99, +111,109,112,108,101,116,101,99,97,108,101,110,100,97,114,112,108,97,116,102,111, +114,109,97,114,116,105,99,108,101,115,114,101,113,117,105,114,101,100,109,111, +118,101,109,101,110,116,113,117,101,115,116,105,111,110,98,117,105,108,100,105, +110,103,112,111,108,105,116,105,99,115,112,111,115,115,105,98,108,101,114,101, +108,105,103,105,111,110,112,104,121,115,105,99,97,108,102,101,101,100,98,97,99, +107,114,101,103,105,115,116,101,114,112,105,99,116,117,114,101,115,100,105,115, +97,98,108,101,100,112,114,111,116,111,99,111,108,97,117,100,105,101,110,99,101, +115,101,116,116,105,110,103,115,97,99,116,105,118,105,116,121,101,108,101,109, +101,110,116,115,108,101,97,114,110,105,110,103,97,110,121,116,104,105,110,103,97 +,98,115,116,114,97,99,116,112,114,111,103,114,101,115,115,111,118,101,114,118, +105,101,119,109,97,103,97,122,105,110,101,101,99,111,110,111,109,105,99,116,114, +97,105,110,105,110,103,112,114,101,115,115,117,114,101,118,97,114,105,111,117, +115,32,60,115,116,114,111,110,103,62,112,114,111,112,101,114,116,121,115,104,111 +,112,112,105,110,103,116,111,103,101,116,104,101,114,97,100,118,97,110,99,101, +100,98,101,104,97,118,105,111,114,100,111,119,110,108,111,97,100,102,101,97,116, +117,114,101,100,102,111,111,116,98,97,108,108,115,101,108,101,99,116,101,100,76, +97,110,103,117,97,103,101,100,105,115,116,97,110,99,101,114,101,109,101,109,98, +101,114,116,114,97,99,107,105,110,103,112,97,115,115,119,111,114,100,109,111,100 +,105,102,105,101,100,115,116,117,100,101,110,116,115,100,105,114,101,99,116,108, +121,102,105,103,104,116,105,110,103,110,111,114,116,104,101,114,110,100,97,116, +97,98,97,115,101,102,101,115,116,105,118,97,108,98,114,101,97,107,105,110,103, +108,111,99,97,116,105,111,110,105,110,116,101,114,110,101,116,100,114,111,112, +100,111,119,110,112,114,97,99,116,105,99,101,101,118,105,100,101,110,99,101,102, +117,110,99,116,105,111,110,109,97,114,114,105,97,103,101,114,101,115,112,111,110 +,115,101,112,114,111,98,108,101,109,115,110,101,103,97,116,105,118,101,112,114, +111,103,114,97,109,115,97,110,97,108,121,115,105,115,114,101,108,101,97,115,101, +100,98,97,110,110,101,114,34,62,112,117,114,99,104,97,115,101,112,111,108,105,99 +,105,101,115,114,101,103,105,111,110,97,108,99,114,101,97,116,105,118,101,97,114 +,103,117,109,101,110,116,98,111,111,107,109,97,114,107,114,101,102,101,114,114, +101,114,99,104,101,109,105,99,97,108,100,105,118,105,115,105,111,110,99,97,108, +108,98,97,99,107,115,101,112,97,114,97,116,101,112,114,111,106,101,99,116,115,99 +,111,110,102,108,105,99,116,104,97,114,100,119,97,114,101,105,110,116,101,114, +101,115,116,100,101,108,105,118,101,114,121,109,111,117,110,116,97,105,110,111, +98,116,97,105,110,101,100,61,32,102,97,108,115,101,59,102,111,114,40,118,97,114, +32,97,99,99,101,112,116,101,100,99,97,112,97,99,105,116,121,99,111,109,112,117, +116,101,114,105,100,101,110,116,105,116,121,97,105,114,99,114,97,102,116,101,109 +,112,108,111,121,101,100,112,114,111,112,111,115,101,100,100,111,109,101,115,116 +,105,99,105,110,99,108,117,100,101,115,112,114,111,118,105,100,101,100,104,111, +115,112,105,116,97,108,118,101,114,116,105,99,97,108,99,111,108,108,97,112,115, +101,97,112,112,114,111,97,99,104,112,97,114,116,110,101,114,115,108,111,103,111, +34,62,60,97,100,97,117,103,104,116,101,114,97,117,116,104,111,114,34,32,99,117, +108,116,117,114,97,108,102,97,109,105,108,105,101,115,47,105,109,97,103,101,115, +47,97,115,115,101,109,98,108,121,112,111,119,101,114,102,117,108,116,101,97,99, +104,105,110,103,102,105,110,105,115,104,101,100,100,105,115,116,114,105,99,116, +99,114,105,116,105,99,97,108,99,103,105,45,98,105,110,47,112,117,114,112,111,115 +,101,115,114,101,113,117,105,114,101,115,101,108,101,99,116,105,111,110,98,101, +99,111,109,105,110,103,112,114,111,118,105,100,101,115,97,99,97,100,101,109,105, +99,101,120,101,114,99,105,115,101,97,99,116,117,97,108,108,121,109,101,100,105, +99,105,110,101,99,111,110,115,116,97,110,116,97,99,99,105,100,101,110,116,77,97, +103,97,122,105,110,101,100,111,99,117,109,101,110,116,115,116,97,114,116,105,110 +,103,98,111,116,116,111,109,34,62,111,98,115,101,114,118,101,100,58,32,38,113, +117,111,116,59,101,120,116,101,110,100,101,100,112,114,101,118,105,111,117,115, +83,111,102,116,119,97,114,101,99,117,115,116,111,109,101,114,100,101,99,105,115, +105,111,110,115,116,114,101,110,103,116,104,100,101,116,97,105,108,101,100,115, +108,105,103,104,116,108,121,112,108,97,110,110,105,110,103,116,101,120,116,97, +114,101,97,99,117,114,114,101,110,99,121,101,118,101,114,121,111,110,101,115,116 +,114,97,105,103,104,116,116,114,97,110,115,102,101,114,112,111,115,105,116,105, +118,101,112,114,111,100,117,99,101,100,104,101,114,105,116,97,103,101,115,104, +105,112,112,105,110,103,97,98,115,111,108,117,116,101,114,101,99,101,105,118,101 +,100,114,101,108,101,118,97,110,116,98,117,116,116,111,110,34,32,118,105,111,108 +,101,110,99,101,97,110,121,119,104,101,114,101,98,101,110,101,102,105,116,115, +108,97,117,110,99,104,101,100,114,101,99,101,110,116,108,121,97,108,108,105,97, +110,99,101,102,111,108,108,111,119,101,100,109,117,108,116,105,112,108,101,98, +117,108,108,101,116,105,110,105,110,99,108,117,100,101,100,111,99,99,117,114,114 +,101,100,105,110,116,101,114,110,97,108,36,40,116,104,105,115,41,46,114,101,112, +117,98,108,105,99,62,60,116,114,62,60,116,100,99,111,110,103,114,101,115,115,114 +,101,99,111,114,100,101,100,117,108,116,105,109,97,116,101,115,111,108,117,116, +105,111,110,60,117,108,32,105,100,61,34,100,105,115,99,111,118,101,114,72,111, +109,101,60,47,97,62,119,101,98,115,105,116,101,115,110,101,116,119,111,114,107, +115,97,108,116,104,111,117,103,104,101,110,116,105,114,101,108,121,109,101,109, +111,114,105,97,108,109,101,115,115,97,103,101,115,99,111,110,116,105,110,117,101 +,97,99,116,105,118,101,34,62,115,111,109,101,119,104,97,116,118,105,99,116,111, +114,105,97,87,101,115,116,101,114,110,32,32,116,105,116,108,101,61,34,76,111,99, +97,116,105,111,110,99,111,110,116,114,97,99,116,118,105,115,105,116,111,114,115, +68,111,119,110,108,111,97,100,119,105,116,104,111,117,116,32,114,105,103,104,116 +,34,62,10,109,101,97,115,117,114,101,115,119,105,100,116,104,32,61,32,118,97,114 +,105,97,98,108,101,105,110,118,111,108,118,101,100,118,105,114,103,105,110,105, +97,110,111,114,109,97,108,108,121,104,97,112,112,101,110,101,100,97,99,99,111, +117,110,116,115,115,116,97,110,100,105,110,103,110,97,116,105,111,110,97,108,82, +101,103,105,115,116,101,114,112,114,101,112,97,114,101,100,99,111,110,116,114, +111,108,115,97,99,99,117,114,97,116,101,98,105,114,116,104,100,97,121,115,116, +114,97,116,101,103,121,111,102,102,105,99,105,97,108,103,114,97,112,104,105,99, +115,99,114,105,109,105,110,97,108,112,111,115,115,105,98,108,121,99,111,110,115, +117,109,101,114,80,101,114,115,111,110,97,108,115,112,101,97,107,105,110,103,118 +,97,108,105,100,97,116,101,97,99,104,105,101,118,101,100,46,106,112,103,34,32,47 +,62,109,97,99,104,105,110,101,115,60,47,104,50,62,10,32,32,107,101,121,119,111, +114,100,115,102,114,105,101,110,100,108,121,98,114,111,116,104,101,114,115,99, +111,109,98,105,110,101,100,111,114,105,103,105,110,97,108,99,111,109,112,111,115 +,101,100,101,120,112,101,99,116,101,100,97,100,101,113,117,97,116,101,112,97,107 +,105,115,116,97,110,102,111,108,108,111,119,34,32,118,97,108,117,97,98,108,101, +60,47,108,97,98,101,108,62,114,101,108,97,116,105,118,101,98,114,105,110,103,105 +,110,103,105,110,99,114,101,97,115,101,103,111,118,101,114,110,111,114,112,108, +117,103,105,110,115,47,76,105,115,116,32,111,102,32,72,101,97,100,101,114,34,62, +34,32,110,97,109,101,61,34,32,40,38,113,117,111,116,59,103,114,97,100,117,97,116 +,101,60,47,104,101,97,100,62,10,99,111,109,109,101,114,99,101,109,97,108,97,121, +115,105,97,100,105,114,101,99,116,111,114,109,97,105,110,116,97,105,110,59,104, +101,105,103,104,116,58,115,99,104,101,100,117,108,101,99,104,97,110,103,105,110, +103,98,97,99,107,32,116,111,32,99,97,116,104,111,108,105,99,112,97,116,116,101, +114,110,115,99,111,108,111,114,58,32,35,103,114,101,97,116,101,115,116,115,117, +112,112,108,105,101,115,114,101,108,105,97,98,108,101,60,47,117,108,62,10,9,9,60 +,115,101,108,101,99,116,32,99,105,116,105,122,101,110,115,99,108,111,116,104,105 +,110,103,119,97,116,99,104,105,110,103,60,108,105,32,105,100,61,34,115,112,101, +99,105,102,105,99,99,97,114,114,121,105,110,103,115,101,110,116,101,110,99,101, +60,99,101,110,116,101,114,62,99,111,110,116,114,97,115,116,116,104,105,110,107, +105,110,103,99,97,116,99,104,40,101,41,115,111,117,116,104,101,114,110,77,105,99 +,104,97,101,108,32,109,101,114,99,104,97,110,116,99,97,114,111,117,115,101,108, +112,97,100,100,105,110,103,58,105,110,116,101,114,105,111,114,46,115,112,108,105 +,116,40,34,108,105,122,97,116,105,111,110,79,99,116,111,98,101,114,32,41,123,114 +,101,116,117,114,110,105,109,112,114,111,118,101,100,45,45,38,103,116,59,10,10, +99,111,118,101,114,97,103,101,99,104,97,105,114,109,97,110,46,112,110,103,34,32, +47,62,115,117,98,106,101,99,116,115,82,105,99,104,97,114,100,32,119,104,97,116, +101,118,101,114,112,114,111,98,97,98,108,121,114,101,99,111,118,101,114,121,98, +97,115,101,98,97,108,108,106,117,100,103,109,101,110,116,99,111,110,110,101,99, +116,46,46,99,115,115,34,32,47,62,32,119,101,98,115,105,116,101,114,101,112,111, +114,116,101,100,100,101,102,97,117,108,116,34,47,62,60,47,97,62,13,10,101,108, +101,99,116,114,105,99,115,99,111,116,108,97,110,100,99,114,101,97,116,105,111, +110,113,117,97,110,116,105,116,121,46,32,73,83,66,78,32,48,100,105,100,32,110, +111,116,32,105,110,115,116,97,110,99,101,45,115,101,97,114,99,104,45,34,32,108, +97,110,103,61,34,115,112,101,97,107,101,114,115,67,111,109,112,117,116,101,114, +99,111,110,116,97,105,110,115,97,114,99,104,105,118,101,115,109,105,110,105,115, +116,101,114,114,101,97,99,116,105,111,110,100,105,115,99,111,117,110,116,73,116, +97,108,105,97,110,111,99,114,105,116,101,114,105,97,115,116,114,111,110,103,108, +121,58,32,39,104,116,116,112,58,39,115,99,114,105,112,116,39,99,111,118,101,114, +105,110,103,111,102,102,101,114,105,110,103,97,112,112,101,97,114,101,100,66,114 +,105,116,105,115,104,32,105,100,101,110,116,105,102,121,70,97,99,101,98,111,111, +107,110,117,109,101,114,111,117,115,118,101,104,105,99,108,101,115,99,111,110,99 +,101,114,110,115,65,109,101,114,105,99,97,110,104,97,110,100,108,105,110,103,100 +,105,118,32,105,100,61,34,87,105,108,108,105,97,109,32,112,114,111,118,105,100, +101,114,95,99,111,110,116,101,110,116,97,99,99,117,114,97,99,121,115,101,99,116, +105,111,110,32,97,110,100,101,114,115,111,110,102,108,101,120,105,98,108,101,67, +97,116,101,103,111,114,121,108,97,119,114,101,110,99,101,60,115,99,114,105,112, +116,62,108,97,121,111,117,116,61,34,97,112,112,114,111,118,101,100,32,109,97,120 +,105,109,117,109,104,101,97,100,101,114,34,62,60,47,116,97,98,108,101,62,83,101, +114,118,105,99,101,115,104,97,109,105,108,116,111,110,99,117,114,114,101,110,116 +,32,99,97,110,97,100,105,97,110,99,104,97,110,110,101,108,115,47,116,104,101,109 +,101,115,47,47,97,114,116,105,99,108,101,111,112,116,105,111,110,97,108,112,111, +114,116,117,103,97,108,118,97,108,117,101,61,34,34,105,110,116,101,114,118,97, +108,119,105,114,101,108,101,115,115,101,110,116,105,116,108,101,100,97,103,101, +110,99,105,101,115,83,101,97,114,99,104,34,32,109,101,97,115,117,114,101,100,116 +,104,111,117,115,97,110,100,115,112,101,110,100,105,110,103,38,104,101,108,108, +105,112,59,110,101,119,32,68,97,116,101,34,32,115,105,122,101,61,34,112,97,103, +101,78,97,109,101,109,105,100,100,108,101,34,32,34,32,47,62,60,47,97,62,104,105, +100,100,101,110,34,62,115,101,113,117,101,110,99,101,112,101,114,115,111,110,97, +108,111,118,101,114,102,108,111,119,111,112,105,110,105,111,110,115,105,108,108, +105,110,111,105,115,108,105,110,107,115,34,62,10,9,60,116,105,116,108,101,62,118 +,101,114,115,105,111,110,115,115,97,116,117,114,100,97,121,116,101,114,109,105, +110,97,108,105,116,101,109,112,114,111,112,101,110,103,105,110,101,101,114,115, +101,99,116,105,111,110,115,100,101,115,105,103,110,101,114,112,114,111,112,111, +115,97,108,61,34,102,97,108,115,101,34,69,115,112,97,195,177,111,108,114,101,108 +,101,97,115,101,115,115,117,98,109,105,116,34,32,101,114,38,113,117,111,116,59, +97,100,100,105,116,105,111,110,115,121,109,112,116,111,109,115,111,114,105,101, +110,116,101,100,114,101,115,111,117,114,99,101,114,105,103,104,116,34,62,60,112, +108,101,97,115,117,114,101,115,116,97,116,105,111,110,115,104,105,115,116,111, +114,121,46,108,101,97,118,105,110,103,32,32,98,111,114,100,101,114,61,99,111,110 +,116,101,110,116,115,99,101,110,116,101,114,34,62,46,10,10,83,111,109,101,32,100 +,105,114,101,99,116,101,100,115,117,105,116,97,98,108,101,98,117,108,103,97,114, +105,97,46,115,104,111,119,40,41,59,100,101,115,105,103,110,101,100,71,101,110, +101,114,97,108,32,99,111,110,99,101,112,116,115,69,120,97,109,112,108,101,115, +119,105,108,108,105,97,109,115,79,114,105,103,105,110,97,108,34,62,60,115,112,97 +,110,62,115,101,97,114,99,104,34,62,111,112,101,114,97,116,111,114,114,101,113, +117,101,115,116,115,97,32,38,113,117,111,116,59,97,108,108,111,119,105,110,103, +68,111,99,117,109,101,110,116,114,101,118,105,115,105,111,110,46,32,10,10,84,104 +,101,32,121,111,117,114,115,101,108,102,67,111,110,116,97,99,116,32,109,105,99, +104,105,103,97,110,69,110,103,108,105,115,104,32,99,111,108,117,109,98,105,97, +112,114,105,111,114,105,116,121,112,114,105,110,116,105,110,103,100,114,105,110, +107,105,110,103,102,97,99,105,108,105,116,121,114,101,116,117,114,110,101,100,67 +,111,110,116,101,110,116,32,111,102,102,105,99,101,114,115,82,117,115,115,105,97 +,110,32,103,101,110,101,114,97,116,101,45,56,56,53,57,45,49,34,105,110,100,105, +99,97,116,101,102,97,109,105,108,105,97,114,32,113,117,97,108,105,116,121,109,97 +,114,103,105,110,58,48,32,99,111,110,116,101,110,116,118,105,101,119,112,111,114 +,116,99,111,110,116,97,99,116,115,45,116,105,116,108,101,34,62,112,111,114,116, +97,98,108,101,46,108,101,110,103,116,104,32,101,108,105,103,105,98,108,101,105, +110,118,111,108,118,101,115,97,116,108,97,110,116,105,99,111,110,108,111,97,100, +61,34,100,101,102,97,117,108,116,46,115,117,112,112,108,105,101,100,112,97,121, +109,101,110,116,115,103,108,111,115,115,97,114,121,10,10,65,102,116,101,114,32, +103,117,105,100,97,110,99,101,60,47,116,100,62,60,116,100,101,110,99,111,100,105 +,110,103,109,105,100,100,108,101,34,62,99,97,109,101,32,116,111,32,100,105,115, +112,108,97,121,115,115,99,111,116,116,105,115,104,106,111,110,97,116,104,97,110, +109,97,106,111,114,105,116,121,119,105,100,103,101,116,115,46,99,108,105,110,105 +,99,97,108,116,104,97,105,108,97,110,100,116,101,97,99,104,101,114,115,60,104, +101,97,100,62,10,9,97,102,102,101,99,116,101,100,115,117,112,112,111,114,116,115 +,112,111,105,110,116,101,114,59,116,111,83,116,114,105,110,103,60,47,115,109,97, +108,108,62,111,107,108,97,104,111,109,97,119,105,108,108,32,98,101,32,105,110, +118,101,115,116,111,114,48,34,32,97,108,116,61,34,104,111,108,105,100,97,121,115 +,82,101,115,111,117,114,99,101,108,105,99,101,110,115,101,100,32,40,119,104,105, +99,104,32,46,32,65,102,116,101,114,32,99,111,110,115,105,100,101,114,118,105,115 +,105,116,105,110,103,101,120,112,108,111,114,101,114,112,114,105,109,97,114,121, +32,115,101,97,114,99,104,34,32,97,110,100,114,111,105,100,34,113,117,105,99,107, +108,121,32,109,101,101,116,105,110,103,115,101,115,116,105,109,97,116,101,59,114 +,101,116,117,114,110,32,59,99,111,108,111,114,58,35,32,104,101,105,103,104,116, +61,97,112,112,114,111,118,97,108,44,32,38,113,117,111,116,59,32,99,104,101,99, +107,101,100,46,109,105,110,46,106,115,34,109,97,103,110,101,116,105,99,62,60,47, +97,62,60,47,104,102,111,114,101,99,97,115,116,46,32,87,104,105,108,101,32,116, +104,117,114,115,100,97,121,100,118,101,114,116,105,115,101,38,101,97,99,117,116, +101,59,104,97,115,67,108,97,115,115,101,118,97,108,117,97,116,101,111,114,100, +101,114,105,110,103,101,120,105,115,116,105,110,103,112,97,116,105,101,110,116, +115,32,79,110,108,105,110,101,32,99,111,108,111,114,97,100,111,79,112,116,105, +111,110,115,34,99,97,109,112,98,101,108,108,60,33,45,45,32,101,110,100,60,47,115 +,112,97,110,62,60,60,98,114,32,47,62,13,10,95,112,111,112,117,112,115,124,115,99 +,105,101,110,99,101,115,44,38,113,117,111,116,59,32,113,117,97,108,105,116,121, +32,87,105,110,100,111,119,115,32,97,115,115,105,103,110,101,100,104,101,105,103, +104,116,58,32,60,98,32,99,108,97,115,115,108,101,38,113,117,111,116,59,32,118,97 +,108,117,101,61,34,32,67,111,109,112,97,110,121,101,120,97,109,112,108,101,115, +60,105,102,114,97,109,101,32,98,101,108,105,101,118,101,115,112,114,101,115,101, +110,116,115,109,97,114,115,104,97,108,108,112,97,114,116,32,111,102,32,112,114, +111,112,101,114,108,121,41,46,10,10,84,104,101,32,116,97,120,111,110,111,109,121 +,109,117,99,104,32,111,102,32,60,47,115,112,97,110,62,10,34,32,100,97,116,97,45, +115,114,116,117,103,117,195,170,115,115,99,114,111,108,108,84,111,32,112,114,111 +,106,101,99,116,60,104,101,97,100,62,13,10,97,116,116,111,114,110,101,121,101, +109,112,104,97,115,105,115,115,112,111,110,115,111,114,115,102,97,110,99,121,98, +111,120,119,111,114,108,100,39,115,32,119,105,108,100,108,105,102,101,99,104,101 +,99,107,101,100,61,115,101,115,115,105,111,110,115,112,114,111,103,114,97,109, +109,112,120,59,102,111,110,116,45,32,80,114,111,106,101,99,116,106,111,117,114, +110,97,108,115,98,101,108,105,101,118,101,100,118,97,99,97,116,105,111,110,116, +104,111,109,112,115,111,110,108,105,103,104,116,105,110,103,97,110,100,32,116, +104,101,32,115,112,101,99,105,97,108,32,98,111,114,100,101,114,61,48,99,104,101, +99,107,105,110,103,60,47,116,98,111,100,121,62,60,98,117,116,116,111,110,32,67, +111,109,112,108,101,116,101,99,108,101,97,114,102,105,120,10,60,104,101,97,100, +62,10,97,114,116,105,99,108,101,32,60,115,101,99,116,105,111,110,102,105,110,100 +,105,110,103,115,114,111,108,101,32,105,110,32,112,111,112,117,108,97,114,32,32, +79,99,116,111,98,101,114,119,101,98,115,105,116,101,32,101,120,112,111,115,117, +114,101,117,115,101,100,32,116,111,32,32,99,104,97,110,103,101,115,111,112,101, +114,97,116,101,100,99,108,105,99,107,105,110,103,101,110,116,101,114,105,110,103 +,99,111,109,109,97,110,100,115,105,110,102,111,114,109,101,100,32,110,117,109,98 +,101,114,115,32,32,60,47,100,105,118,62,99,114,101,97,116,105,110,103,111,110,83 +,117,98,109,105,116,109,97,114,121,108,97,110,100,99,111,108,108,101,103,101,115 +,97,110,97,108,121,116,105,99,108,105,115,116,105,110,103,115,99,111,110,116,97, +99,116,46,108,111,103,103,101,100,73,110,97,100,118,105,115,111,114,121,115,105, +98,108,105,110,103,115,99,111,110,116,101,110,116,34,115,38,113,117,111,116,59, +41,115,46,32,84,104,105,115,32,112,97,99,107,97,103,101,115,99,104,101,99,107,98 +,111,120,115,117,103,103,101,115,116,115,112,114,101,103,110,97,110,116,116,111, +109,111,114,114,111,119,115,112,97,99,105,110,103,61,105,99,111,110,46,112,110, +103,106,97,112,97,110,101,115,101,99,111,100,101,98,97,115,101,98,117,116,116, +111,110,34,62,103,97,109,98,108,105,110,103,115,117,99,104,32,97,115,32,44,32, +119,104,105,108,101,32,60,47,115,112,97,110,62,32,109,105,115,115,111,117,114, +105,115,112,111,114,116,105,110,103,116,111,112,58,49,112,120,32,46,60,47,115, +112,97,110,62,116,101,110,115,105,111,110,115,119,105,100,116,104,61,34,50,108, +97,122,121,108,111,97,100,110,111,118,101,109,98,101,114,117,115,101,100,32,105, +110,32,104,101,105,103,104,116,61,34,99,114,105,112,116,34,62,10,38,110,98,115, +112,59,60,47,60,116,114,62,60,116,100,32,104,101,105,103,104,116,58,50,47,112, +114,111,100,117,99,116,99,111,117,110,116,114,121,32,105,110,99,108,117,100,101, +32,102,111,111,116,101,114,34,32,38,108,116,59,33,45,45,32,116,105,116,108,101, +34,62,60,47,106,113,117,101,114,121,46,60,47,102,111,114,109,62,10,40,231,174, +128,228,189,147,41,40,231,185,129,233,171,148,41,104,114,118,97,116,115,107,105, +105,116,97,108,105,97,110,111,114,111,109,195,162,110,196,131,116,195,188,114, +107,195,167,101,216,167,216,177,216,175,217,136,116,97,109,98,105,195,169,110, +110,111,116,105,99,105,97,115,109,101,110,115,97,106,101,115,112,101,114,115,111 +,110,97,115,100,101,114,101,99,104,111,115,110,97,99,105,111,110,97,108,115,101, +114,118,105,99,105,111,99,111,110,116,97,99,116,111,117,115,117,97,114,105,111, +115,112,114,111,103,114,97,109,97,103,111,98,105,101,114,110,111,101,109,112,114 +,101,115,97,115,97,110,117,110,99,105,111,115,118,97,108,101,110,99,105,97,99, +111,108,111,109,98,105,97,100,101,115,112,117,195,169,115,100,101,112,111,114, +116,101,115,112,114,111,121,101,99,116,111,112,114,111,100,117,99,116,111,112, +195,186,98,108,105,99,111,110,111,115,111,116,114,111,115,104,105,115,116,111, +114,105,97,112,114,101,115,101,110,116,101,109,105,108,108,111,110,101,115,109, +101,100,105,97,110,116,101,112,114,101,103,117,110,116,97,97,110,116,101,114,105 +,111,114,114,101,99,117,114,115,111,115,112,114,111,98,108,101,109,97,115,97,110 +,116,105,97,103,111,110,117,101,115,116,114,111,115,111,112,105,110,105,195,179, +110,105,109,112,114,105,109,105,114,109,105,101,110,116,114,97,115,97,109,195, +169,114,105,99,97,118,101,110,100,101,100,111,114,115,111,99,105,101,100,97,100, +114,101,115,112,101,99,116,111,114,101,97,108,105,122,97,114,114,101,103,105,115 +,116,114,111,112,97,108,97,98,114,97,115,105,110,116,101,114,195,169,115,101,110 +,116,111,110,99,101,115,101,115,112,101,99,105,97,108,109,105,101,109,98,114,111 +,115,114,101,97,108,105,100,97,100,99,195,179,114,100,111,98,97,122,97,114,97, +103,111,122,97,112,195,161,103,105,110,97,115,115,111,99,105,97,108,101,115,98, +108,111,113,117,101,97,114,103,101,115,116,105,195,179,110,97,108,113,117,105, +108,101,114,115,105,115,116,101,109,97,115,99,105,101,110,99,105,97,115,99,111, +109,112,108,101,116,111,118,101,114,115,105,195,179,110,99,111,109,112,108,101, +116,97,101,115,116,117,100,105,111,115,112,195,186,98,108,105,99,97,111,98,106, +101,116,105,118,111,97,108,105,99,97,110,116,101,98,117,115,99,97,100,111,114,99 +,97,110,116,105,100,97,100,101,110,116,114,97,100,97,115,97,99,99,105,111,110, +101,115,97,114,99,104,105,118,111,115,115,117,112,101,114,105,111,114,109,97,121 +,111,114,195,173,97,97,108,101,109,97,110,105,97,102,117,110,99,105,195,179,110, +195,186,108,116,105,109,111,115,104,97,99,105,101,110,100,111,97,113,117,101,108 +,108,111,115,101,100,105,99,105,195,179,110,102,101,114,110,97,110,100,111,97, +109,98,105,101,110,116,101,102,97,99,101,98,111,111,107,110,117,101,115,116,114, +97,115,99,108,105,101,110,116,101,115,112,114,111,99,101,115,111,115,98,97,115, +116,97,110,116,101,112,114,101,115,101,110,116,97,114,101,112,111,114,116,97,114 +,99,111,110,103,114,101,115,111,112,117,98,108,105,99,97,114,99,111,109,101,114, +99,105,111,99,111,110,116,114,97,116,111,106,195,179,118,101,110,101,115,100,105 +,115,116,114,105,116,111,116,195,169,99,110,105,99,97,99,111,110,106,117,110,116 +,111,101,110,101,114,103,195,173,97,116,114,97,98,97,106,97,114,97,115,116,117, +114,105,97,115,114,101,99,105,101,110,116,101,117,116,105,108,105,122,97,114,98, +111,108,101,116,195,173,110,115,97,108,118,97,100,111,114,99,111,114,114,101,99, +116,97,116,114,97,98,97,106,111,115,112,114,105,109,101,114,111,115,110,101,103, +111,99,105,111,115,108,105,98,101,114,116,97,100,100,101,116,97,108,108,101,115, +112,97,110,116,97,108,108,97,112,114,195,179,120,105,109,111,97,108,109,101,114, +195,173,97,97,110,105,109,97,108,101,115,113,117,105,195,169,110,101,115,99,111, +114,97,122,195,179,110,115,101,99,99,105,195,179,110,98,117,115,99,97,110,100, +111,111,112,99,105,111,110,101,115,101,120,116,101,114,105,111,114,99,111,110,99 +,101,112,116,111,116,111,100,97,118,195,173,97,103,97,108,101,114,195,173,97,101 +,115,99,114,105,98,105,114,109,101,100,105,99,105,110,97,108,105,99,101,110,99, +105,97,99,111,110,115,117,108,116,97,97,115,112,101,99,116,111,115,99,114,195, +173,116,105,99,97,100,195,179,108,97,114,101,115,106,117,115,116,105,99,105,97, +100,101,98,101,114,195,161,110,112,101,114,195,173,111,100,111,110,101,99,101, +115,105,116,97,109,97,110,116,101,110,101,114,112,101,113,117,101,195,177,111, +114,101,99,105,98,105,100,97,116,114,105,98,117,110,97,108,116,101,110,101,114, +105,102,101,99,97,110,99,105,195,179,110,99,97,110,97,114,105,97,115,100,101,115 +,99,97,114,103,97,100,105,118,101,114,115,111,115,109,97,108,108,111,114,99,97, +114,101,113,117,105,101,114,101,116,195,169,99,110,105,99,111,100,101,98,101,114 +,195,173,97,118,105,118,105,101,110,100,97,102,105,110,97,110,122,97,115,97,100, +101,108,97,110,116,101,102,117,110,99,105,111,110,97,99,111,110,115,101,106,111, +115,100,105,102,195,173,99,105,108,99,105,117,100,97,100,101,115,97,110,116,105, +103,117,97,115,97,118,97,110,122,97,100,97,116,195,169,114,109,105,110,111,117, +110,105,100,97,100,101,115,115,195,161,110,99,104,101,122,99,97,109,112,97,195, +177,97,115,111,102,116,111,110,105,99,114,101,118,105,115,116,97,115,99,111,110, +116,105,101,110,101,115,101,99,116,111,114,101,115,109,111,109,101,110,116,111, +115,102,97,99,117,108,116,97,100,99,114,195,169,100,105,116,111,100,105,118,101, +114,115,97,115,115,117,112,117,101,115,116,111,102,97,99,116,111,114,101,115,115 +,101,103,117,110,100,111,115,112,101,113,117,101,195,177,97,208,179,208,190,208, +180,208,176,208,181,209,129,208,187,208,184,208,181,209,129,209,130,209,140,208, +177,209,139,208,187,208,190,208,177,209,139,209,130,209,140,209,141,209,130,208, +190,208,188,208,149,209,129,208,187,208,184,209,130,208,190,208,179,208,190,208, +188,208,181,208,189,209,143,208,178,209,129,208,181,209,133,209,141,209,130,208, +190,208,185,208,180,208,176,208,182,208,181,208,177,209,139,208,187,208,184,208, +179,208,190,208,180,209,131,208,180,208,181,208,189,209,140,209,141,209,130,208, +190,209,130,208,177,209,139,208,187,208,176,209,129,208,181,208,177,209,143,208, +190,208,180,208,184,208,189,209,129,208,181,208,177,208,181,208,189,208,176,208, +180,208,190,209,129,208,176,208,185,209,130,209,132,208,190,209,130,208,190,208, +189,208,181,208,179,208,190,209,129,208,178,208,190,208,184,209,129,208,178,208, +190,208,185,208,184,208,179,209,128,209,139,209,130,208,190,208,182,208,181,208, +178,209,129,208,181,208,188,209,129,208,178,208,190,209,142,208,187,208,184,209, +136,209,140,209,141,209,130,208,184,209,133,208,191,208,190,208,186,208,176,208, +180,208,189,208,181,208,185,208,180,208,190,208,188,208,176,208,188,208,184,209, +128,208,176,208,187,208,184,208,177,208,190,209,130,208,181,208,188,209,131,209, +133,208,190,209,130,209,143,208,180,208,178,209,131,209,133,209,129,208,181,209, +130,208,184,208,187,209,142,208,180,208,184,208,180,208,181,208,187,208,190,208, +188,208,184,209,128,208,181,209,130,208,181,208,177,209,143,209,129,208,178,208, +190,208,181,208,178,208,184,208,180,208,181,209,135,208,181,208,179,208,190,209, +141,209,130,208,184,208,188,209,129,209,135,208,181,209,130,209,130,208,181,208, +188,209,139,209,134,208,181,208,189,209,139,209,129,209,130,208,176,208,187,208, +178,208,181,208,180,209,140,209,130,208,181,208,188,208,181,208,178,208,190,208, +180,209,139,209,130,208,181,208,177,208,181,208,178,209,139,209,136,208,181,208, +189,208,176,208,188,208,184,209,130,208,184,208,191,208,176,209,130,208,190,208, +188,209,131,208,191,209,128,208,176,208,178,208,187,208,184,209,134,208,176,208, +190,208,180,208,189,208,176,208,179,208,190,208,180,209,139,208,183,208,189,208, +176,209,142,208,188,208,190,208,179,209,131,208,180,209,128,209,131,208,179,208, +178,209,129,208,181,208,185,208,184,208,180,208,181,209,130,208,186,208,184,208, +189,208,190,208,190,208,180,208,189,208,190,208,180,208,181,208,187,208,176,208, +180,208,181,208,187,208,181,209,129,209,128,208,190,208,186,208,184,209,142,208, +189,209,143,208,178,208,181,209,129,209,140,208,149,209,129,209,130,209,140,209, +128,208,176,208,183,208,176,208,189,208,176,209,136,208,184,216,167,217,132,217, +132,217,135,216,167,217,132,216,170,217,138,216,172,217,133,217,138,216,185,216, +174,216,167,216,181,216,169,216,167,217,132,216,176,217,138,216,185,217,132,217, +138,217,135,216,172,216,175,217,138,216,175,216,167,217,132,216,162,217,134,216, +167,217,132,216,177,216,175,216,170,216,173,217,131,217,133,216,181,217,129,216, +173,216,169,217,131,216,167,217,134,216,170,216,167,217,132,217,132,217,138,217, +138,217,131,217,136,217,134,216,180,216,168,217,131,216,169,217,129,217,138,217, +135,216,167,216,168,217,134,216,167,216,170,216,173,217,136,216,167,216,161,216, +163,217,131,216,171,216,177,216,174,217,132,216,167,217,132,216,167,217,132,216, +173,216,168,216,175,217,132,217,138,217,132,216,175,216,177,217,136,216,179,216, +167,216,182,216,186,216,183,216,170,217,131,217,136,217,134,217,135,217,134,216, +167,217,131,216,179,216,167,216,173,216,169,217,134,216,167,216,175,217,138,216, +167,217,132,216,183,216,168,216,185,217,132,217,138,217,131,216,180,217,131,216, +177,216,167,217,138,217,133,217,131,217,134,217,133,217,134,217,135,216,167,216, +180,216,177,217,131,216,169,216,177,216,166,217,138,216,179,217,134,216,180,217, +138,216,183,217,133,216,167,216,176,216,167,216,167,217,132,217,129,217,134,216, +180,216,168,216,167,216,168,216,170,216,185,216,168,216,177,216,177,216,173,217, +133,216,169,217,131,216,167,217,129,216,169,217,138,217,130,217,136,217,132,217, +133,216,177,217,131,216,178,217,131,217,132,217,133,216,169,216,163,216,173,217, +133,216,175,217,130,217,132,216,168,217,138,217,138,216,185,217,134,217,138,216, +181,217,136,216,177,216,169,216,183,216,177,217,138,217,130,216,180,216,167,216, +177,217,131,216,172,217,136,216,167,217,132,216,163,216,174,216,177,217,137,217, +133,216,185,217,134,216,167,216,167,216,168,216,173,216,171,216,185,216,177,217, +136,216,182,216,168,216,180,217,131,217,132,217,133,216,179,216,172,217,132,216, +168,217,134,216,167,217,134,216,174,216,167,217,132,216,175,217,131,216,170,216, +167,216,168,217,131,217,132,217,138,216,169,216,168,216,175,217,136,217,134,216, +163,217,138,216,182,216,167,217,138,217,136,216,172,216,175,217,129,216,177,217, +138,217,130,217,131,216,170,216,168,216,170,216,163,217,129,216,182,217,132,217, +133,216,183,216,168,216,174,216,167,217,131,216,171,216,177,216,168,216,167,216, +177,217,131,216,167,217,129,216,182,217,132,216,167,216,173,217,132,217,137,217, +134,217,129,216,179,217,135,216,163,217,138,216,167,217,133,216,177,216,175,217, +136,216,175,216,163,217,134,217,135,216,167,216,175,217,138,217,134,216,167,216, +167,217,132,216,167,217,134,217,133,216,185,216,177,216,182,216,170,216,185,217, +132,217,133,216,175,216,167,216,174,217,132,217,133,217,133,217,131,217,134,0,0, +0,0,0,0,0,0,1,0,1,0,1,0,1,0,2,0,2,0,2,0,2,0,4,0,4,0,4,0,4,0,0,1,2,3,4,5,6,7,7,6, +5,4,3,2,1,0,8,9,10,11,12,13,14,15,15,14,13,12,11,10,9,8,16,17,18,19,20,21,22,23, +23,22,21,20,19,18,17,16,24,25,26,27,28,29,30,31,31,30,29,28,27,26,25,24,255,255, +255,255,0,0,0,0,0,0,0,0,255,255,255,255,1,0,0,0,2,0,0,0,2,0,0,0,1,0,0,0,1,0,0,0, +3,0,0,0,255,255,0,1,0,0,0,1,0,0,255,255,0,1,0,0,0,8,0,8,0,8,0,8,0,0,0,1,0,2,0,3, +0,4,0,5,0,6,0,7,114,101,115,111,117,114,99,101,115,99,111,117,110,116,114,105, +101,115,113,117,101,115,116,105,111,110,115,101,113,117,105,112,109,101,110,116, +99,111,109,109,117,110,105,116,121,97,118,97,105,108,97,98,108,101,104,105,103, +104,108,105,103,104,116,68,84,68,47,120,104,116,109,108,109,97,114,107,101,116, +105,110,103,107,110,111,119,108,101,100,103,101,115,111,109,101,116,104,105,110, +103,99,111,110,116,97,105,110,101,114,100,105,114,101,99,116,105,111,110,115,117 +,98,115,99,114,105,98,101,97,100,118,101,114,116,105,115,101,99,104,97,114,97,99 +,116,101,114,34,32,118,97,108,117,101,61,34,60,47,115,101,108,101,99,116,62,65, +117,115,116,114,97,108,105,97,34,32,99,108,97,115,115,61,34,115,105,116,117,97, +116,105,111,110,97,117,116,104,111,114,105,116,121,102,111,108,108,111,119,105, +110,103,112,114,105,109,97,114,105,108,121,111,112,101,114,97,116,105,111,110,99 +,104,97,108,108,101,110,103,101,100,101,118,101,108,111,112,101,100,97,110,111, +110,121,109,111,117,115,102,117,110,99,116,105,111,110,32,102,117,110,99,116,105 +,111,110,115,99,111,109,112,97,110,105,101,115,115,116,114,117,99,116,117,114, +101,97,103,114,101,101,109,101,110,116,34,32,116,105,116,108,101,61,34,112,111, +116,101,110,116,105,97,108,101,100,117,99,97,116,105,111,110,97,114,103,117,109, +101,110,116,115,115,101,99,111,110,100,97,114,121,99,111,112,121,114,105,103,104 +,116,108,97,110,103,117,97,103,101,115,101,120,99,108,117,115,105,118,101,99,111 +,110,100,105,116,105,111,110,60,47,102,111,114,109,62,13,10,115,116,97,116,101, +109,101,110,116,97,116,116,101,110,116,105,111,110,66,105,111,103,114,97,112,104 +,121,125,32,101,108,115,101,32,123,10,115,111,108,117,116,105,111,110,115,119, +104,101,110,32,116,104,101,32,65,110,97,108,121,116,105,99,115,116,101,109,112, +108,97,116,101,115,100,97,110,103,101,114,111,117,115,115,97,116,101,108,108,105 +,116,101,100,111,99,117,109,101,110,116,115,112,117,98,108,105,115,104,101,114, +105,109,112,111,114,116,97,110,116,112,114,111,116,111,116,121,112,101,105,110, +102,108,117,101,110,99,101,38,114,97,113,117,111,59,60,47,101,102,102,101,99,116 +,105,118,101,103,101,110,101,114,97,108,108,121,116,114,97,110,115,102,111,114, +109,98,101,97,117,116,105,102,117,108,116,114,97,110,115,112,111,114,116,111,114 +,103,97,110,105,122,101,100,112,117,98,108,105,115,104,101,100,112,114,111,109, +105,110,101,110,116,117,110,116,105,108,32,116,104,101,116,104,117,109,98,110,97 +,105,108,78,97,116,105,111,110,97,108,32,46,102,111,99,117,115,40,41,59,111,118, +101,114,32,116,104,101,32,109,105,103,114,97,116,105,111,110,97,110,110,111,117, +110,99,101,100,102,111,111,116,101,114,34,62,10,101,120,99,101,112,116,105,111, +110,108,101,115,115,32,116,104,97,110,101,120,112,101,110,115,105,118,101,102, +111,114,109,97,116,105,111,110,102,114,97,109,101,119,111,114,107,116,101,114, +114,105,116,111,114,121,110,100,105,99,97,116,105,111,110,99,117,114,114,101,110 +,116,108,121,99,108,97,115,115,78,97,109,101,99,114,105,116,105,99,105,115,109, +116,114,97,100,105,116,105,111,110,101,108,115,101,119,104,101,114,101,65,108, +101,120,97,110,100,101,114,97,112,112,111,105,110,116,101,100,109,97,116,101,114 +,105,97,108,115,98,114,111,97,100,99,97,115,116,109,101,110,116,105,111,110,101, +100,97,102,102,105,108,105,97,116,101,60,47,111,112,116,105,111,110,62,116,114, +101,97,116,109,101,110,116,100,105,102,102,101,114,101,110,116,47,100,101,102,97 +,117,108,116,46,80,114,101,115,105,100,101,110,116,111,110,99,108,105,99,107,61, +34,98,105,111,103,114,97,112,104,121,111,116,104,101,114,119,105,115,101,112,101 +,114,109,97,110,101,110,116,70,114,97,110,195,167,97,105,115,72,111,108,108,121, +119,111,111,100,101,120,112,97,110,115,105,111,110,115,116,97,110,100,97,114,100 +,115,60,47,115,116,121,108,101,62,10,114,101,100,117,99,116,105,111,110,68,101, +99,101,109,98,101,114,32,112,114,101,102,101,114,114,101,100,67,97,109,98,114, +105,100,103,101,111,112,112,111,110,101,110,116,115,66,117,115,105,110,101,115, +115,32,99,111,110,102,117,115,105,111,110,62,10,60,116,105,116,108,101,62,112, +114,101,115,101,110,116,101,100,101,120,112,108,97,105,110,101,100,100,111,101, +115,32,110,111,116,32,119,111,114,108,100,119,105,100,101,105,110,116,101,114, +102,97,99,101,112,111,115,105,116,105,111,110,115,110,101,119,115,112,97,112,101 +,114,60,47,116,97,98,108,101,62,10,109,111,117,110,116,97,105,110,115,108,105, +107,101,32,116,104,101,32,101,115,115,101,110,116,105,97,108,102,105,110,97,110, +99,105,97,108,115,101,108,101,99,116,105,111,110,97,99,116,105,111,110,61,34,47, +97,98,97,110,100,111,110,101,100,69,100,117,99,97,116,105,111,110,112,97,114,115 +,101,73,110,116,40,115,116,97,98,105,108,105,116,121,117,110,97,98,108,101,32, +116,111,60,47,116,105,116,108,101,62,10,114,101,108,97,116,105,111,110,115,78, +111,116,101,32,116,104,97,116,101,102,102,105,99,105,101,110,116,112,101,114,102 +,111,114,109,101,100,116,119,111,32,121,101,97,114,115,83,105,110,99,101,32,116, +104,101,116,104,101,114,101,102,111,114,101,119,114,97,112,112,101,114,34,62,97, +108,116,101,114,110,97,116,101,105,110,99,114,101,97,115,101,100,66,97,116,116, +108,101,32,111,102,112,101,114,99,101,105,118,101,100,116,114,121,105,110,103,32 +,116,111,110,101,99,101,115,115,97,114,121,112,111,114,116,114,97,121,101,100, +101,108,101,99,116,105,111,110,115,69,108,105,122,97,98,101,116,104,60,47,105, +102,114,97,109,101,62,100,105,115,99,111,118,101,114,121,105,110,115,117,114,97, +110,99,101,115,46,108,101,110,103,116,104,59,108,101,103,101,110,100,97,114,121, +71,101,111,103,114,97,112,104,121,99,97,110,100,105,100,97,116,101,99,111,114, +112,111,114,97,116,101,115,111,109,101,116,105,109,101,115,115,101,114,118,105, +99,101,115,46,105,110,104,101,114,105,116,101,100,60,47,115,116,114,111,110,103, +62,67,111,109,109,117,110,105,116,121,114,101,108,105,103,105,111,117,115,108, +111,99,97,116,105,111,110,115,67,111,109,109,105,116,116,101,101,98,117,105,108, +100,105,110,103,115,116,104,101,32,119,111,114,108,100,110,111,32,108,111,110, +103,101,114,98,101,103,105,110,110,105,110,103,114,101,102,101,114,101,110,99, +101,99,97,110,110,111,116,32,98,101,102,114,101,113,117,101,110,99,121,116,121, +112,105,99,97,108,108,121,105,110,116,111,32,116,104,101,32,114,101,108,97,116, +105,118,101,59,114,101,99,111,114,100,105,110,103,112,114,101,115,105,100,101, +110,116,105,110,105,116,105,97,108,108,121,116,101,99,104,110,105,113,117,101, +116,104,101,32,111,116,104,101,114,105,116,32,99,97,110,32,98,101,101,120,105, +115,116,101,110,99,101,117,110,100,101,114,108,105,110,101,116,104,105,115,32, +116,105,109,101,116,101,108,101,112,104,111,110,101,105,116,101,109,115,99,111, +112,101,112,114,97,99,116,105,99,101,115,97,100,118,97,110,116,97,103,101,41,59, +114,101,116,117,114,110,32,70,111,114,32,111,116,104,101,114,112,114,111,118,105 +,100,105,110,103,100,101,109,111,99,114,97,99,121,98,111,116,104,32,116,104,101, +32,101,120,116,101,110,115,105,118,101,115,117,102,102,101,114,105,110,103,115, +117,112,112,111,114,116,101,100,99,111,109,112,117,116,101,114,115,32,102,117, +110,99,116,105,111,110,112,114,97,99,116,105,99,97,108,115,97,105,100,32,116,104 +,97,116,105,116,32,109,97,121,32,98,101,69,110,103,108,105,115,104,60,47,102,114 +,111,109,32,116,104,101,32,115,99,104,101,100,117,108,101,100,100,111,119,110, +108,111,97,100,115,60,47,108,97,98,101,108,62,10,115,117,115,112,101,99,116,101, +100,109,97,114,103,105,110,58,32,48,115,112,105,114,105,116,117,97,108,60,47,104 +,101,97,100,62,10,10,109,105,99,114,111,115,111,102,116,103,114,97,100,117,97, +108,108,121,100,105,115,99,117,115,115,101,100,104,101,32,98,101,99,97,109,101, +101,120,101,99,117,116,105,118,101,106,113,117,101,114,121,46,106,115,104,111, +117,115,101,104,111,108,100,99,111,110,102,105,114,109,101,100,112,117,114,99, +104,97,115,101,100,108,105,116,101,114,97,108,108,121,100,101,115,116,114,111, +121,101,100,117,112,32,116,111,32,116,104,101,118,97,114,105,97,116,105,111,110, +114,101,109,97,105,110,105,110,103,105,116,32,105,115,32,110,111,116,99,101,110, +116,117,114,105,101,115,74,97,112,97,110,101,115,101,32,97,109,111,110,103,32, +116,104,101,99,111,109,112,108,101,116,101,100,97,108,103,111,114,105,116,104, +109,105,110,116,101,114,101,115,116,115,114,101,98,101,108,108,105,111,110,117, +110,100,101,102,105,110,101,100,101,110,99,111,117,114,97,103,101,114,101,115, +105,122,97,98,108,101,105,110,118,111,108,118,105,110,103,115,101,110,115,105, +116,105,118,101,117,110,105,118,101,114,115,97,108,112,114,111,118,105,115,105, +111,110,40,97,108,116,104,111,117,103,104,102,101,97,116,117,114,105,110,103,99, +111,110,100,117,99,116,101,100,41,44,32,119,104,105,99,104,32,99,111,110,116,105 +,110,117,101,100,45,104,101,97,100,101,114,34,62,70,101,98,114,117,97,114,121,32 +,110,117,109,101,114,111,117,115,32,111,118,101,114,102,108,111,119,58,99,111, +109,112,111,110,101,110,116,102,114,97,103,109,101,110,116,115,101,120,99,101, +108,108,101,110,116,99,111,108,115,112,97,110,61,34,116,101,99,104,110,105,99,97 +,108,110,101,97,114,32,116,104,101,32,65,100,118,97,110,99,101,100,32,115,111, +117,114,99,101,32,111,102,101,120,112,114,101,115,115,101,100,72,111,110,103,32, +75,111,110,103,32,70,97,99,101,98,111,111,107,109,117,108,116,105,112,108,101,32 +,109,101,99,104,97,110,105,115,109,101,108,101,118,97,116,105,111,110,111,102, +102,101,110,115,105,118,101,60,47,102,111,114,109,62,10,9,115,112,111,110,115, +111,114,101,100,100,111,99,117,109,101,110,116,46,111,114,32,38,113,117,111,116, +59,116,104,101,114,101,32,97,114,101,116,104,111,115,101,32,119,104,111,109,111, +118,101,109,101,110,116,115,112,114,111,99,101,115,115,101,115,100,105,102,102, +105,99,117,108,116,115,117,98,109,105,116,116,101,100,114,101,99,111,109,109,101 +,110,100,99,111,110,118,105,110,99,101,100,112,114,111,109,111,116,105,110,103, +34,32,119,105,100,116,104,61,34,46,114,101,112,108,97,99,101,40,99,108,97,115, +115,105,99,97,108,99,111,97,108,105,116,105,111,110,104,105,115,32,102,105,114, +115,116,100,101,99,105,115,105,111,110,115,97,115,115,105,115,116,97,110,116,105 +,110,100,105,99,97,116,101,100,101,118,111,108,117,116,105,111,110,45,119,114,97 +,112,112,101,114,34,101,110,111,117,103,104,32,116,111,97,108,111,110,103,32,116 +,104,101,100,101,108,105,118,101,114,101,100,45,45,62,13,10,60,33,45,45,65,109, +101,114,105,99,97,110,32,112,114,111,116,101,99,116,101,100,78,111,118,101,109, +98,101,114,32,60,47,115,116,121,108,101,62,60,102,117,114,110,105,116,117,114, +101,73,110,116,101,114,110,101,116,32,32,111,110,98,108,117,114,61,34,115,117, +115,112,101,110,100,101,100,114,101,99,105,112,105,101,110,116,98,97,115,101,100 +,32,111,110,32,77,111,114,101,111,118,101,114,44,97,98,111,108,105,115,104,101, +100,99,111,108,108,101,99,116,101,100,119,101,114,101,32,109,97,100,101,101,109, +111,116,105,111,110,97,108,101,109,101,114,103,101,110,99,121,110,97,114,114,97, +116,105,118,101,97,100,118,111,99,97,116,101,115,112,120,59,98,111,114,100,101, +114,99,111,109,109,105,116,116,101,100,100,105,114,61,34,108,116,114,34,101,109, +112,108,111,121,101,101,115,114,101,115,101,97,114,99,104,46,32,115,101,108,101, +99,116,101,100,115,117,99,99,101,115,115,111,114,99,117,115,116,111,109,101,114, +115,100,105,115,112,108,97,121,101,100,83,101,112,116,101,109,98,101,114,97,100, +100,67,108,97,115,115,40,70,97,99,101,98,111,111,107,32,115,117,103,103,101,115, +116,101,100,97,110,100,32,108,97,116,101,114,111,112,101,114,97,116,105,110,103, +101,108,97,98,111,114,97,116,101,83,111,109,101,116,105,109,101,115,73,110,115, +116,105,116,117,116,101,99,101,114,116,97,105,110,108,121,105,110,115,116,97,108 +,108,101,100,102,111,108,108,111,119,101,114,115,74,101,114,117,115,97,108,101, +109,116,104,101,121,32,104,97,118,101,99,111,109,112,117,116,105,110,103,103,101 +,110,101,114,97,116,101,100,112,114,111,118,105,110,99,101,115,103,117,97,114,97 +,110,116,101,101,97,114,98,105,116,114,97,114,121,114,101,99,111,103,110,105,122 +,101,119,97,110,116,101,100,32,116,111,112,120,59,119,105,100,116,104,58,116,104 +,101,111,114,121,32,111,102,98,101,104,97,118,105,111,117,114,87,104,105,108,101 +,32,116,104,101,101,115,116,105,109,97,116,101,100,98,101,103,97,110,32,116,111, +32,105,116,32,98,101,99,97,109,101,109,97,103,110,105,116,117,100,101,109,117, +115,116,32,104,97,118,101,109,111,114,101,32,116,104,97,110,68,105,114,101,99, +116,111,114,121,101,120,116,101,110,115,105,111,110,115,101,99,114,101,116,97, +114,121,110,97,116,117,114,97,108,108,121,111,99,99,117,114,114,105,110,103,118, +97,114,105,97,98,108,101,115,103,105,118,101,110,32,116,104,101,112,108,97,116, +102,111,114,109,46,60,47,108,97,98,101,108,62,60,102,97,105,108,101,100,32,116, +111,99,111,109,112,111,117,110,100,115,107,105,110,100,115,32,111,102,32,115,111 +,99,105,101,116,105,101,115,97,108,111,110,103,115,105,100,101,32,45,45,38,103, +116,59,10,10,115,111,117,116,104,119,101,115,116,116,104,101,32,114,105,103,104, +116,114,97,100,105,97,116,105,111,110,109,97,121,32,104,97,118,101,32,117,110, +101,115,99,97,112,101,40,115,112,111,107,101,110,32,105,110,34,32,104,114,101, +102,61,34,47,112,114,111,103,114,97,109,109,101,111,110,108,121,32,116,104,101, +32,99,111,109,101,32,102,114,111,109,100,105,114,101,99,116,111,114,121,98,117, +114,105,101,100,32,105,110,97,32,115,105,109,105,108,97,114,116,104,101,121,32, +119,101,114,101,60,47,102,111,110,116,62,60,47,78,111,114,119,101,103,105,97,110 +,115,112,101,99,105,102,105,101,100,112,114,111,100,117,99,105,110,103,112,97, +115,115,101,110,103,101,114,40,110,101,119,32,68,97,116,101,116,101,109,112,111, +114,97,114,121,102,105,99,116,105,111,110,97,108,65,102,116,101,114,32,116,104, +101,101,113,117,97,116,105,111,110,115,100,111,119,110,108,111,97,100,46,114,101 +,103,117,108,97,114,108,121,100,101,118,101,108,111,112,101,114,97,98,111,118, +101,32,116,104,101,108,105,110,107,101,100,32,116,111,112,104,101,110,111,109, +101,110,97,112,101,114,105,111,100,32,111,102,116,111,111,108,116,105,112,34,62, +115,117,98,115,116,97,110,99,101,97,117,116,111,109,97,116,105,99,97,115,112,101 +,99,116,32,111,102,65,109,111,110,103,32,116,104,101,99,111,110,110,101,99,116, +101,100,101,115,116,105,109,97,116,101,115,65,105,114,32,70,111,114,99,101,115, +121,115,116,101,109,32,111,102,111,98,106,101,99,116,105,118,101,105,109,109,101 +,100,105,97,116,101,109,97,107,105,110,103,32,105,116,112,97,105,110,116,105,110 +,103,115,99,111,110,113,117,101,114,101,100,97,114,101,32,115,116,105,108,108, +112,114,111,99,101,100,117,114,101,103,114,111,119,116,104,32,111,102,104,101,97 +,100,101,100,32,98,121,69,117,114,111,112,101,97,110,32,100,105,118,105,115,105, +111,110,115,109,111,108,101,99,117,108,101,115,102,114,97,110,99,104,105,115,101 +,105,110,116,101,110,116,105,111,110,97,116,116,114,97,99,116,101,100,99,104,105 +,108,100,104,111,111,100,97,108,115,111,32,117,115,101,100,100,101,100,105,99,97 +,116,101,100,115,105,110,103,97,112,111,114,101,100,101,103,114,101,101,32,111, +102,102,97,116,104,101,114,32,111,102,99,111,110,102,108,105,99,116,115,60,47,97 +,62,60,47,112,62,10,99,97,109,101,32,102,114,111,109,119,101,114,101,32,117,115, +101,100,110,111,116,101,32,116,104,97,116,114,101,99,101,105,118,105,110,103,69, +120,101,99,117,116,105,118,101,101,118,101,110,32,109,111,114,101,97,99,99,101, +115,115,32,116,111,99,111,109,109,97,110,100,101,114,80,111,108,105,116,105,99, +97,108,109,117,115,105,99,105,97,110,115,100,101,108,105,99,105,111,117,115,112, +114,105,115,111,110,101,114,115,97,100,118,101,110,116,32,111,102,85,84,70,45,56 +,34,32,47,62,60,33,91,67,68,65,84,65,91,34,62,67,111,110,116,97,99,116,83,111, +117,116,104,101,114,110,32,98,103,99,111,108,111,114,61,34,115,101,114,105,101, +115,32,111,102,46,32,73,116,32,119,97,115,32,105,110,32,69,117,114,111,112,101, +112,101,114,109,105,116,116,101,100,118,97,108,105,100,97,116,101,46,97,112,112, +101,97,114,105,110,103,111,102,102,105,99,105,97,108,115,115,101,114,105,111,117 +,115,108,121,45,108,97,110,103,117,97,103,101,105,110,105,116,105,97,116,101,100 +,101,120,116,101,110,100,105,110,103,108,111,110,103,45,116,101,114,109,105,110, +102,108,97,116,105,111,110,115,117,99,104,32,116,104,97,116,103,101,116,67,111, +111,107,105,101,109,97,114,107,101,100,32,98,121,60,47,98,117,116,116,111,110,62 +,105,109,112,108,101,109,101,110,116,98,117,116,32,105,116,32,105,115,105,110,99 +,114,101,97,115,101,115,100,111,119,110,32,116,104,101,32,114,101,113,117,105, +114,105,110,103,100,101,112,101,110,100,101,110,116,45,45,62,10,60,33,45,45,32, +105,110,116,101,114,118,105,101,119,87,105,116,104,32,116,104,101,32,99,111,112, +105,101,115,32,111,102,99,111,110,115,101,110,115,117,115,119,97,115,32,98,117, +105,108,116,86,101,110,101,122,117,101,108,97,40,102,111,114,109,101,114,108,121 +,116,104,101,32,115,116,97,116,101,112,101,114,115,111,110,110,101,108,115,116, +114,97,116,101,103,105,99,102,97,118,111,117,114,32,111,102,105,110,118,101,110, +116,105,111,110,87,105,107,105,112,101,100,105,97,99,111,110,116,105,110,101,110 +,116,118,105,114,116,117,97,108,108,121,119,104,105,99,104,32,119,97,115,112,114 +,105,110,99,105,112,108,101,67,111,109,112,108,101,116,101,32,105,100,101,110, +116,105,99,97,108,115,104,111,119,32,116,104,97,116,112,114,105,109,105,116,105, +118,101,97,119,97,121,32,102,114,111,109,109,111,108,101,99,117,108,97,114,112, +114,101,99,105,115,101,108,121,100,105,115,115,111,108,118,101,100,85,110,100, +101,114,32,116,104,101,118,101,114,115,105,111,110,61,34,62,38,110,98,115,112,59 +,60,47,73,116,32,105,115,32,116,104,101,32,84,104,105,115,32,105,115,32,119,105, +108,108,32,104,97,118,101,111,114,103,97,110,105,115,109,115,115,111,109,101,32, +116,105,109,101,70,114,105,101,100,114,105,99,104,119,97,115,32,102,105,114,115, +116,116,104,101,32,111,110,108,121,32,102,97,99,116,32,116,104,97,116,102,111, +114,109,32,105,100,61,34,112,114,101,99,101,100,105,110,103,84,101,99,104,110, +105,99,97,108,112,104,121,115,105,99,105,115,116,111,99,99,117,114,115,32,105, +110,110,97,118,105,103,97,116,111,114,115,101,99,116,105,111,110,34,62,115,112, +97,110,32,105,100,61,34,115,111,117,103,104,116,32,116,111,98,101,108,111,119,32 +,116,104,101,115,117,114,118,105,118,105,110,103,125,60,47,115,116,121,108,101, +62,104,105,115,32,100,101,97,116,104,97,115,32,105,110,32,116,104,101,99,97,117, +115,101,100,32,98,121,112,97,114,116,105,97,108,108,121,101,120,105,115,116,105, +110,103,32,117,115,105,110,103,32,116,104,101,119,97,115,32,103,105,118,101,110, +97,32,108,105,115,116,32,111,102,108,101,118,101,108,115,32,111,102,110,111,116, +105,111,110,32,111,102,79,102,102,105,99,105,97,108,32,100,105,115,109,105,115, +115,101,100,115,99,105,101,110,116,105,115,116,114,101,115,101,109,98,108,101, +115,100,117,112,108,105,99,97,116,101,101,120,112,108,111,115,105,118,101,114, +101,99,111,118,101,114,101,100,97,108,108,32,111,116,104,101,114,103,97,108,108, +101,114,105,101,115,123,112,97,100,100,105,110,103,58,112,101,111,112,108,101,32 +,111,102,114,101,103,105,111,110,32,111,102,97,100,100,114,101,115,115,101,115, +97,115,115,111,99,105,97,116,101,105,109,103,32,97,108,116,61,34,105,110,32,109, +111,100,101,114,110,115,104,111,117,108,100,32,98,101,109,101,116,104,111,100,32 +,111,102,114,101,112,111,114,116,105,110,103,116,105,109,101,115,116,97,109,112, +110,101,101,100,101,100,32,116,111,116,104,101,32,71,114,101,97,116,114,101,103, +97,114,100,105,110,103,115,101,101,109,101,100,32,116,111,118,105,101,119,101, +100,32,97,115,105,109,112,97,99,116,32,111,110,105,100,101,97,32,116,104,97,116, +116,104,101,32,87,111,114,108,100,104,101,105,103,104,116,32,111,102,101,120,112 +,97,110,100,105,110,103,84,104,101,115,101,32,97,114,101,99,117,114,114,101,110, +116,34,62,99,97,114,101,102,117,108,108,121,109,97,105,110,116,97,105,110,115,99 +,104,97,114,103,101,32,111,102,67,108,97,115,115,105,99,97,108,97,100,100,114, +101,115,115,101,100,112,114,101,100,105,99,116,101,100,111,119,110,101,114,115, +104,105,112,60,100,105,118,32,105,100,61,34,114,105,103,104,116,34,62,13,10,114, +101,115,105,100,101,110,99,101,108,101,97,118,101,32,116,104,101,99,111,110,116, +101,110,116,34,62,97,114,101,32,111,102,116,101,110,32,32,125,41,40,41,59,13,10, +112,114,111,98,97,98,108,121,32,80,114,111,102,101,115,115,111,114,45,98,117,116 +,116,111,110,34,32,114,101,115,112,111,110,100,101,100,115,97,121,115,32,116,104 +,97,116,104,97,100,32,116,111,32,98,101,112,108,97,99,101,100,32,105,110,72,117, +110,103,97,114,105,97,110,115,116,97,116,117,115,32,111,102,115,101,114,118,101, +115,32,97,115,85,110,105,118,101,114,115,97,108,101,120,101,99,117,116,105,111, +110,97,103,103,114,101,103,97,116,101,102,111,114,32,119,104,105,99,104,105,110, +102,101,99,116,105,111,110,97,103,114,101,101,100,32,116,111,104,111,119,101,118 +,101,114,44,32,112,111,112,117,108,97,114,34,62,112,108,97,99,101,100,32,111,110 +,99,111,110,115,116,114,117,99,116,101,108,101,99,116,111,114,97,108,115,121,109 +,98,111,108,32,111,102,105,110,99,108,117,100,105,110,103,114,101,116,117,114, +110,32,116,111,97,114,99,104,105,116,101,99,116,67,104,114,105,115,116,105,97, +110,112,114,101,118,105,111,117,115,32,108,105,118,105,110,103,32,105,110,101,97 +,115,105,101,114,32,116,111,112,114,111,102,101,115,115,111,114,10,38,108,116,59 +,33,45,45,32,101,102,102,101,99,116,32,111,102,97,110,97,108,121,116,105,99,115, +119,97,115,32,116,97,107,101,110,119,104,101,114,101,32,116,104,101,116,111,111, +107,32,111,118,101,114,98,101,108,105,101,102,32,105,110,65,102,114,105,107,97, +97,110,115,97,115,32,102,97,114,32,97,115,112,114,101,118,101,110,116,101,100, +119,111,114,107,32,119,105,116,104,97,32,115,112,101,99,105,97,108,60,102,105, +101,108,100,115,101,116,67,104,114,105,115,116,109,97,115,82,101,116,114,105,101 +,118,101,100,10,10,73,110,32,116,104,101,32,98,97,99,107,32,105,110,116,111,110, +111,114,116,104,101,97,115,116,109,97,103,97,122,105,110,101,115,62,60,115,116, +114,111,110,103,62,99,111,109,109,105,116,116,101,101,103,111,118,101,114,110, +105,110,103,103,114,111,117,112,115,32,111,102,115,116,111,114,101,100,32,105, +110,101,115,116,97,98,108,105,115,104,97,32,103,101,110,101,114,97,108,105,116, +115,32,102,105,114,115,116,116,104,101,105,114,32,111,119,110,112,111,112,117, +108,97,116,101,100,97,110,32,111,98,106,101,99,116,67,97,114,105,98,98,101,97, +110,97,108,108,111,119,32,116,104,101,100,105,115,116,114,105,99,116,115,119,105 +,115,99,111,110,115,105,110,108,111,99,97,116,105,111,110,46,59,32,119,105,100, +116,104,58,32,105,110,104,97,98,105,116,101,100,83,111,99,105,97,108,105,115,116 +,74,97,110,117,97,114,121,32,49,60,47,102,111,111,116,101,114,62,115,105,109,105 +,108,97,114,108,121,99,104,111,105,99,101,32,111,102,116,104,101,32,115,97,109, +101,32,115,112,101,99,105,102,105,99,32,98,117,115,105,110,101,115,115,32,84,104 +,101,32,102,105,114,115,116,46,108,101,110,103,116,104,59,32,100,101,115,105,114 +,101,32,116,111,100,101,97,108,32,119,105,116,104,115,105,110,99,101,32,116,104, +101,117,115,101,114,65,103,101,110,116,99,111,110,99,101,105,118,101,100,105,110 +,100,101,120,46,112,104,112,97,115,32,38,113,117,111,116,59,101,110,103,97,103, +101,32,105,110,114,101,99,101,110,116,108,121,44,102,101,119,32,121,101,97,114, +115,119,101,114,101,32,97,108,115,111,10,60,104,101,97,100,62,10,60,101,100,105, +116,101,100,32,98,121,97,114,101,32,107,110,111,119,110,99,105,116,105,101,115, +32,105,110,97,99,99,101,115,115,107,101,121,99,111,110,100,101,109,110,101,100, +97,108,115,111,32,104,97,118,101,115,101,114,118,105,99,101,115,44,102,97,109, +105,108,121,32,111,102,83,99,104,111,111,108,32,111,102,99,111,110,118,101,114, +116,101,100,110,97,116,117,114,101,32,111,102,32,108,97,110,103,117,97,103,101, +109,105,110,105,115,116,101,114,115,60,47,111,98,106,101,99,116,62,116,104,101, +114,101,32,105,115,32,97,32,112,111,112,117,108,97,114,115,101,113,117,101,110, +99,101,115,97,100,118,111,99,97,116,101,100,84,104,101,121,32,119,101,114,101,97 +,110,121,32,111,116,104,101,114,108,111,99,97,116,105,111,110,61,101,110,116,101 +,114,32,116,104,101,109,117,99,104,32,109,111,114,101,114,101,102,108,101,99,116 +,101,100,119,97,115,32,110,97,109,101,100,111,114,105,103,105,110,97,108,32,97, +32,116,121,112,105,99,97,108,119,104,101,110,32,116,104,101,121,101,110,103,105, +110,101,101,114,115,99,111,117,108,100,32,110,111,116,114,101,115,105,100,101, +110,116,115,119,101,100,110,101,115,100,97,121,116,104,101,32,116,104,105,114, +100,32,112,114,111,100,117,99,116,115,74,97,110,117,97,114,121,32,50,119,104,97, +116,32,116,104,101,121,97,32,99,101,114,116,97,105,110,114,101,97,99,116,105,111 +,110,115,112,114,111,99,101,115,115,111,114,97,102,116,101,114,32,104,105,115, +116,104,101,32,108,97,115,116,32,99,111,110,116,97,105,110,101,100,34,62,60,47, +100,105,118,62,10,60,47,97,62,60,47,116,100,62,100,101,112,101,110,100,32,111, +110,115,101,97,114,99,104,34,62,10,112,105,101,99,101,115,32,111,102,99,111,109, +112,101,116,105,110,103,82,101,102,101,114,101,110,99,101,116,101,110,110,101, +115,115,101,101,119,104,105,99,104,32,104,97,115,32,118,101,114,115,105,111,110, +61,60,47,115,112,97,110,62,32,60,60,47,104,101,97,100,101,114,62,103,105,118,101 +,115,32,116,104,101,104,105,115,116,111,114,105,97,110,118,97,108,117,101,61,34, +34,62,112,97,100,100,105,110,103,58,48,118,105,101,119,32,116,104,97,116,116,111 +,103,101,116,104,101,114,44,116,104,101,32,109,111,115,116,32,119,97,115,32,102, +111,117,110,100,115,117,98,115,101,116,32,111,102,97,116,116,97,99,107,32,111, +110,99,104,105,108,100,114,101,110,44,112,111,105,110,116,115,32,111,102,112,101 +,114,115,111,110,97,108,32,112,111,115,105,116,105,111,110,58,97,108,108,101,103 +,101,100,108,121,67,108,101,118,101,108,97,110,100,119,97,115,32,108,97,116,101, +114,97,110,100,32,97,102,116,101,114,97,114,101,32,103,105,118,101,110,119,97, +115,32,115,116,105,108,108,115,99,114,111,108,108,105,110,103,100,101,115,105, +103,110,32,111,102,109,97,107,101,115,32,116,104,101,109,117,99,104,32,108,101, +115,115,65,109,101,114,105,99,97,110,115,46,10,10,65,102,116,101,114,32,44,32,98 +,117,116,32,116,104,101,77,117,115,101,117,109,32,111,102,108,111,117,105,115, +105,97,110,97,40,102,114,111,109,32,116,104,101,109,105,110,110,101,115,111,116, +97,112,97,114,116,105,99,108,101,115,97,32,112,114,111,99,101,115,115,68,111,109 +,105,110,105,99,97,110,118,111,108,117,109,101,32,111,102,114,101,116,117,114, +110,105,110,103,100,101,102,101,110,115,105,118,101,48,48,112,120,124,114,105, +103,104,109,97,100,101,32,102,114,111,109,109,111,117,115,101,111,118,101,114,34 +,32,115,116,121,108,101,61,34,115,116,97,116,101,115,32,111,102,40,119,104,105, +99,104,32,105,115,99,111,110,116,105,110,117,101,115,70,114,97,110,99,105,115,99 +,111,98,117,105,108,100,105,110,103,32,119,105,116,104,111,117,116,32,97,119,105 +,116,104,32,115,111,109,101,119,104,111,32,119,111,117,108,100,97,32,102,111,114 +,109,32,111,102,97,32,112,97,114,116,32,111,102,98,101,102,111,114,101,32,105, +116,107,110,111,119,110,32,97,115,32,32,83,101,114,118,105,99,101,115,108,111,99 +,97,116,105,111,110,32,97,110,100,32,111,102,116,101,110,109,101,97,115,117,114, +105,110,103,97,110,100,32,105,116,32,105,115,112,97,112,101,114,98,97,99,107,118 +,97,108,117,101,115,32,111,102,13,10,60,116,105,116,108,101,62,61,32,119,105,110 +,100,111,119,46,100,101,116,101,114,109,105,110,101,101,114,38,113,117,111,116, +59,32,112,108,97,121,101,100,32,98,121,97,110,100,32,101,97,114,108,121,60,47,99 +,101,110,116,101,114,62,102,114,111,109,32,116,104,105,115,116,104,101,32,116, +104,114,101,101,112,111,119,101,114,32,97,110,100,111,102,32,38,113,117,111,116, +59,105,110,110,101,114,72,84,77,76,60,97,32,104,114,101,102,61,34,121,58,105,110 +,108,105,110,101,59,67,104,117,114,99,104,32,111,102,116,104,101,32,101,118,101, +110,116,118,101,114,121,32,104,105,103,104,111,102,102,105,99,105,97,108,32,45, +104,101,105,103,104,116,58,32,99,111,110,116,101,110,116,61,34,47,99,103,105,45, +98,105,110,47,116,111,32,99,114,101,97,116,101,97,102,114,105,107,97,97,110,115, +101,115,112,101,114,97,110,116,111,102,114,97,110,195,167,97,105,115,108,97,116, +118,105,101,197,161,117,108,105,101,116,117,118,105,197,179,196,140,101,197,161, +116,105,110,97,196,141,101,197,161,116,105,110,97,224,185,132,224,184,151,224, +184,162,230,151,165,230,156,172,232,170,158,231,174,128,228,189,147,229,173,151, +231,185,129,233,171,148,229,173,151,237,149,156,234,181,173,236,150,180,228,184, +186,228,187,128,228,185,136,232,174,161,231,174,151,230,156,186,231,172,148,232, +174,176,230,156,172,232,168,142,232,171,150,229,141,128,230,156,141,229,138,161, +229,153,168,228,186,146,232,129,148,231,189,145,230,136,191,229,156,176,228,186, +167,228,191,177,228,185,144,233,131,168,229,135,186,231,137,136,231,164,190,230, +142,146,232,161,140,230,166,156,233,131,168,232,144,189,230,160,188,232,191,155, +228,184,128,230,173,165,230,148,175,228,187,152,229,174,157,233,170,140,232,175, +129,231,160,129,229,167,148,229,145,152,228,188,154,230,149,176,230,141,174,229, +186,147,230,182,136,232,180,185,232,128,133,229,138,158,229,133,172,229,174,164, +232,174,168,232,174,186,229,140,186,230,183,177,229,156,179,229,184,130,230,146, +173,230,148,190,229,153,168,229,140,151,228,186,172,229,184,130,229,164,167,229, +173,166,231,148,159,232,182,138,230,157,165,232,182,138,231,174,161,231,144,134, +229,145,152,228,191,161,230,129,175,231,189,145,115,101,114,118,105,99,105,111, +115,97,114,116,195,173,99,117,108,111,97,114,103,101,110,116,105,110,97,98,97, +114,99,101,108,111,110,97,99,117,97,108,113,117,105,101,114,112,117,98,108,105, +99,97,100,111,112,114,111,100,117,99,116,111,115,112,111,108,195,173,116,105,99, +97,114,101,115,112,117,101,115,116,97,119,105,107,105,112,101,100,105,97,115,105 +,103,117,105,101,110,116,101,98,195,186,115,113,117,101,100,97,99,111,109,117, +110,105,100,97,100,115,101,103,117,114,105,100,97,100,112,114,105,110,99,105,112 +,97,108,112,114,101,103,117,110,116,97,115,99,111,110,116,101,110,105,100,111, +114,101,115,112,111,110,100,101,114,118,101,110,101,122,117,101,108,97,112,114, +111,98,108,101,109,97,115,100,105,99,105,101,109,98,114,101,114,101,108,97,99, +105,195,179,110,110,111,118,105,101,109,98,114,101,115,105,109,105,108,97,114, +101,115,112,114,111,121,101,99,116,111,115,112,114,111,103,114,97,109,97,115,105 +,110,115,116,105,116,117,116,111,97,99,116,105,118,105,100,97,100,101,110,99,117 +,101,110,116,114,97,101,99,111,110,111,109,195,173,97,105,109,195,161,103,101, +110,101,115,99,111,110,116,97,99,116,97,114,100,101,115,99,97,114,103,97,114,110 +,101,99,101,115,97,114,105,111,97,116,101,110,99,105,195,179,110,116,101,108,195 +,169,102,111,110,111,99,111,109,105,115,105,195,179,110,99,97,110,99,105,111,110 +,101,115,99,97,112,97,99,105,100,97,100,101,110,99,111,110,116,114,97,114,97,110 +,195,161,108,105,115,105,115,102,97,118,111,114,105,116,111,115,116,195,169,114, +109,105,110,111,115,112,114,111,118,105,110,99,105,97,101,116,105,113,117,101, +116,97,115,101,108,101,109,101,110,116,111,115,102,117,110,99,105,111,110,101, +115,114,101,115,117,108,116,97,100,111,99,97,114,195,161,99,116,101,114,112,114, +111,112,105,101,100,97,100,112,114,105,110,99,105,112,105,111,110,101,99,101,115 +,105,100,97,100,109,117,110,105,99,105,112,97,108,99,114,101,97,99,105,195,179, +110,100,101,115,99,97,114,103,97,115,112,114,101,115,101,110,99,105,97,99,111, +109,101,114,99,105,97,108,111,112,105,110,105,111,110,101,115,101,106,101,114,99 +,105,99,105,111,101,100,105,116,111,114,105,97,108,115,97,108,97,109,97,110,99, +97,103,111,110,122,195,161,108,101,122,100,111,99,117,109,101,110,116,111,112, +101,108,195,173,99,117,108,97,114,101,99,105,101,110,116,101,115,103,101,110,101 +,114,97,108,101,115,116,97,114,114,97,103,111,110,97,112,114,195,161,99,116,105, +99,97,110,111,118,101,100,97,100,101,115,112,114,111,112,117,101,115,116,97,112, +97,99,105,101,110,116,101,115,116,195,169,99,110,105,99,97,115,111,98,106,101, +116,105,118,111,115,99,111,110,116,97,99,116,111,115,224,164,174,224,165,135,224 +,164,130,224,164,178,224,164,191,224,164,143,224,164,185,224,165,136,224,164,130 +,224,164,151,224,164,175,224,164,190,224,164,184,224,164,190,224,164,165,224,164 +,143,224,164,181,224,164,130,224,164,176,224,164,185,224,165,135,224,164,149,224 +,165,139,224,164,136,224,164,149,224,165,129,224,164,155,224,164,176,224,164,185 +,224,164,190,224,164,172,224,164,190,224,164,166,224,164,149,224,164,185,224,164 +,190,224,164,184,224,164,173,224,165,128,224,164,185,224,165,129,224,164,143,224 +,164,176,224,164,185,224,165,128,224,164,174,224,165,136,224,164,130,224,164,166 +,224,164,191,224,164,168,224,164,172,224,164,190,224,164,164,100,105,112,108,111 +,100,111,99,115,224,164,184,224,164,174,224,164,175,224,164,176,224,165,130,224, +164,170,224,164,168,224,164,190,224,164,174,224,164,170,224,164,164,224,164,190, +224,164,171,224,164,191,224,164,176,224,164,148,224,164,184,224,164,164,224,164, +164,224,164,176,224,164,185,224,164,178,224,165,139,224,164,151,224,164,185,224, +165,129,224,164,134,224,164,172,224,164,190,224,164,176,224,164,166,224,165,135, +224,164,182,224,164,185,224,165,129,224,164,136,224,164,150,224,165,135,224,164, +178,224,164,175,224,164,166,224,164,191,224,164,149,224,164,190,224,164,174,224, +164,181,224,165,135,224,164,172,224,164,164,224,165,128,224,164,168,224,164,172, +224,165,128,224,164,154,224,164,174,224,165,140,224,164,164,224,164,184,224,164, +190,224,164,178,224,164,178,224,165,135,224,164,150,224,164,156,224,165,137,224, +164,172,224,164,174,224,164,166,224,164,166,224,164,164,224,164,165,224,164,190, +224,164,168,224,164,185,224,165,128,224,164,182,224,164,185,224,164,176,224,164, +133,224,164,178,224,164,151,224,164,149,224,164,173,224,165,128,224,164,168,224, +164,151,224,164,176,224,164,170,224,164,190,224,164,184,224,164,176,224,164,190, +224,164,164,224,164,149,224,164,191,224,164,143,224,164,137,224,164,184,224,165, +135,224,164,151,224,164,175,224,165,128,224,164,185,224,165,130,224,164,129,224, +164,134,224,164,151,224,165,135,224,164,159,224,165,128,224,164,174,224,164,150, +224,165,139,224,164,156,224,164,149,224,164,190,224,164,176,224,164,133,224,164, +173,224,165,128,224,164,151,224,164,175,224,165,135,224,164,164,224,165,129,224, +164,174,224,164,181,224,165,139,224,164,159,224,164,166,224,165,135,224,164,130, +224,164,133,224,164,151,224,164,176,224,164,144,224,164,184,224,165,135,224,164, +174,224,165,135,224,164,178,224,164,178,224,164,151,224,164,190,224,164,185,224, +164,190,224,164,178,224,164,138,224,164,170,224,164,176,224,164,154,224,164,190, +224,164,176,224,164,144,224,164,184,224,164,190,224,164,166,224,165,135,224,164, +176,224,164,156,224,164,191,224,164,184,224,164,166,224,164,191,224,164,178,224, +164,172,224,164,130,224,164,166,224,164,172,224,164,168,224,164,190,224,164,185, +224,165,130,224,164,130,224,164,178,224,164,190,224,164,150,224,164,156,224,165, +128,224,164,164,224,164,172,224,164,159,224,164,168,224,164,174,224,164,191,224, +164,178,224,164,135,224,164,184,224,165,135,224,164,134,224,164,168,224,165,135, +224,164,168,224,164,175,224,164,190,224,164,149,224,165,129,224,164,178,224,164, +178,224,165,137,224,164,151,224,164,173,224,164,190,224,164,151,224,164,176,224, +165,135,224,164,178,224,164,156,224,164,151,224,164,185,224,164,176,224,164,190, +224,164,174,224,164,178,224,164,151,224,165,135,224,164,170,224,165,135,224,164, +156,224,164,185,224,164,190,224,164,165,224,164,135,224,164,184,224,165,128,224, +164,184,224,164,185,224,165,128,224,164,149,224,164,178,224,164,190,224,164,160, +224,165,128,224,164,149,224,164,185,224,164,190,224,164,129,224,164,166,224,165, +130,224,164,176,224,164,164,224,164,185,224,164,164,224,164,184,224,164,190,224, +164,164,224,164,175,224,164,190,224,164,166,224,164,134,224,164,175,224,164,190, +224,164,170,224,164,190,224,164,149,224,164,149,224,165,140,224,164,168,224,164, +182,224,164,190,224,164,174,224,164,166,224,165,135,224,164,150,224,164,175,224, +164,185,224,165,128,224,164,176,224,164,190,224,164,175,224,164,150,224,165,129, +224,164,166,224,164,178,224,164,151,224,165,128,99,97,116,101,103,111,114,105, +101,115,101,120,112,101,114,105,101,110,99,101,60,47,116,105,116,108,101,62,13, +10,67,111,112,121,114,105,103,104,116,32,106,97,118,97,115,99,114,105,112,116,99 +,111,110,100,105,116,105,111,110,115,101,118,101,114,121,116,104,105,110,103,60, +112,32,99,108,97,115,115,61,34,116,101,99,104,110,111,108,111,103,121,98,97,99, +107,103,114,111,117,110,100,60,97,32,99,108,97,115,115,61,34,109,97,110,97,103, +101,109,101,110,116,38,99,111,112,121,59,32,50,48,49,106,97,118,97,83,99,114,105 +,112,116,99,104,97,114,97,99,116,101,114,115,98,114,101,97,100,99,114,117,109,98 +,116,104,101,109,115,101,108,118,101,115,104,111,114,105,122,111,110,116,97,108, +103,111,118,101,114,110,109,101,110,116,67,97,108,105,102,111,114,110,105,97,97, +99,116,105,118,105,116,105,101,115,100,105,115,99,111,118,101,114,101,100,78,97, +118,105,103,97,116,105,111,110,116,114,97,110,115,105,116,105,111,110,99,111,110 +,110,101,99,116,105,111,110,110,97,118,105,103,97,116,105,111,110,97,112,112,101 +,97,114,97,110,99,101,60,47,116,105,116,108,101,62,60,109,99,104,101,99,107,98, +111,120,34,32,116,101,99,104,110,105,113,117,101,115,112,114,111,116,101,99,116, +105,111,110,97,112,112,97,114,101,110,116,108,121,97,115,32,119,101,108,108,32, +97,115,117,110,116,39,44,32,39,85,65,45,114,101,115,111,108,117,116,105,111,110, +111,112,101,114,97,116,105,111,110,115,116,101,108,101,118,105,115,105,111,110, +116,114,97,110,115,108,97,116,101,100,87,97,115,104,105,110,103,116,111,110,110, +97,118,105,103,97,116,111,114,46,32,61,32,119,105,110,100,111,119,46,105,109,112 +,114,101,115,115,105,111,110,38,108,116,59,98,114,38,103,116,59,108,105,116,101, +114,97,116,117,114,101,112,111,112,117,108,97,116,105,111,110,98,103,99,111,108, +111,114,61,34,35,101,115,112,101,99,105,97,108,108,121,32,99,111,110,116,101,110 +,116,61,34,112,114,111,100,117,99,116,105,111,110,110,101,119,115,108,101,116, +116,101,114,112,114,111,112,101,114,116,105,101,115,100,101,102,105,110,105,116, +105,111,110,108,101,97,100,101,114,115,104,105,112,84,101,99,104,110,111,108,111 +,103,121,80,97,114,108,105,97,109,101,110,116,99,111,109,112,97,114,105,115,111, +110,117,108,32,99,108,97,115,115,61,34,46,105,110,100,101,120,79,102,40,34,99, +111,110,99,108,117,115,105,111,110,100,105,115,99,117,115,115,105,111,110,99,111 +,109,112,111,110,101,110,116,115,98,105,111,108,111,103,105,99,97,108,82,101,118 +,111,108,117,116,105,111,110,95,99,111,110,116,97,105,110,101,114,117,110,100, +101,114,115,116,111,111,100,110,111,115,99,114,105,112,116,62,60,112,101,114,109 +,105,115,115,105,111,110,101,97,99,104,32,111,116,104,101,114,97,116,109,111,115 +,112,104,101,114,101,32,111,110,102,111,99,117,115,61,34,60,102,111,114,109,32, +105,100,61,34,112,114,111,99,101,115,115,105,110,103,116,104,105,115,46,118,97, +108,117,101,103,101,110,101,114,97,116,105,111,110,67,111,110,102,101,114,101, +110,99,101,115,117,98,115,101,113,117,101,110,116,119,101,108,108,45,107,110,111 +,119,110,118,97,114,105,97,116,105,111,110,115,114,101,112,117,116,97,116,105, +111,110,112,104,101,110,111,109,101,110,111,110,100,105,115,99,105,112,108,105, +110,101,108,111,103,111,46,112,110,103,34,32,40,100,111,99,117,109,101,110,116, +44,98,111,117,110,100,97,114,105,101,115,101,120,112,114,101,115,115,105,111,110 +,115,101,116,116,108,101,109,101,110,116,66,97,99,107,103,114,111,117,110,100, +111,117,116,32,111,102,32,116,104,101,101,110,116,101,114,112,114,105,115,101,40 +,34,104,116,116,112,115,58,34,32,117,110,101,115,99,97,112,101,40,34,112,97,115, +115,119,111,114,100,34,32,100,101,109,111,99,114,97,116,105,99,60,97,32,104,114, +101,102,61,34,47,119,114,97,112,112,101,114,34,62,10,109,101,109,98,101,114,115, +104,105,112,108,105,110,103,117,105,115,116,105,99,112,120,59,112,97,100,100,105 +,110,103,112,104,105,108,111,115,111,112,104,121,97,115,115,105,115,116,97,110, +99,101,117,110,105,118,101,114,115,105,116,121,102,97,99,105,108,105,116,105,101 +,115,114,101,99,111,103,110,105,122,101,100,112,114,101,102,101,114,101,110,99, +101,105,102,32,40,116,121,112,101,111,102,109,97,105,110,116,97,105,110,101,100, +118,111,99,97,98,117,108,97,114,121,104,121,112,111,116,104,101,115,105,115,46, +115,117,98,109,105,116,40,41,59,38,97,109,112,59,110,98,115,112,59,97,110,110, +111,116,97,116,105,111,110,98,101,104,105,110,100,32,116,104,101,70,111,117,110, +100,97,116,105,111,110,112,117,98,108,105,115,104,101,114,34,97,115,115,117,109, +112,116,105,111,110,105,110,116,114,111,100,117,99,101,100,99,111,114,114,117, +112,116,105,111,110,115,99,105,101,110,116,105,115,116,115,101,120,112,108,105, +99,105,116,108,121,105,110,115,116,101,97,100,32,111,102,100,105,109,101,110,115 +,105,111,110,115,32,111,110,67,108,105,99,107,61,34,99,111,110,115,105,100,101, +114,101,100,100,101,112,97,114,116,109,101,110,116,111,99,99,117,112,97,116,105, +111,110,115,111,111,110,32,97,102,116,101,114,105,110,118,101,115,116,109,101, +110,116,112,114,111,110,111,117,110,99,101,100,105,100,101,110,116,105,102,105, +101,100,101,120,112,101,114,105,109,101,110,116,77,97,110,97,103,101,109,101,110 +,116,103,101,111,103,114,97,112,104,105,99,34,32,104,101,105,103,104,116,61,34, +108,105,110,107,32,114,101,108,61,34,46,114,101,112,108,97,99,101,40,47,100,101, +112,114,101,115,115,105,111,110,99,111,110,102,101,114,101,110,99,101,112,117, +110,105,115,104,109,101,110,116,101,108,105,109,105,110,97,116,101,100,114,101, +115,105,115,116,97,110,99,101,97,100,97,112,116,97,116,105,111,110,111,112,112, +111,115,105,116,105,111,110,119,101,108,108,32,107,110,111,119,110,115,117,112, +112,108,101,109,101,110,116,100,101,116,101,114,109,105,110,101,100,104,49,32,99 +,108,97,115,115,61,34,48,112,120,59,109,97,114,103,105,110,109,101,99,104,97,110 +,105,99,97,108,115,116,97,116,105,115,116,105,99,115,99,101,108,101,98,114,97, +116,101,100,71,111,118,101,114,110,109,101,110,116,10,10,68,117,114,105,110,103, +32,116,100,101,118,101,108,111,112,101,114,115,97,114,116,105,102,105,99,105,97, +108,101,113,117,105,118,97,108,101,110,116,111,114,105,103,105,110,97,116,101, +100,67,111,109,109,105,115,115,105,111,110,97,116,116,97,99,104,109,101,110,116, +60,115,112,97,110,32,105,100,61,34,116,104,101,114,101,32,119,101,114,101,78,101 +,100,101,114,108,97,110,100,115,98,101,121,111,110,100,32,116,104,101,114,101, +103,105,115,116,101,114,101,100,106,111,117,114,110,97,108,105,115,116,102,114, +101,113,117,101,110,116,108,121,97,108,108,32,111,102,32,116,104,101,108,97,110, +103,61,34,101,110,34,32,60,47,115,116,121,108,101,62,13,10,97,98,115,111,108,117 +,116,101,59,32,115,117,112,112,111,114,116,105,110,103,101,120,116,114,101,109, +101,108,121,32,109,97,105,110,115,116,114,101,97,109,60,47,115,116,114,111,110, +103,62,32,112,111,112,117,108,97,114,105,116,121,101,109,112,108,111,121,109,101 +,110,116,60,47,116,97,98,108,101,62,13,10,32,99,111,108,115,112,97,110,61,34,60, +47,102,111,114,109,62,10,32,32,99,111,110,118,101,114,115,105,111,110,97,98,111, +117,116,32,116,104,101,32,60,47,112,62,60,47,100,105,118,62,105,110,116,101,103, +114,97,116,101,100,34,32,108,97,110,103,61,34,101,110,80,111,114,116,117,103,117 +,101,115,101,115,117,98,115,116,105,116,117,116,101,105,110,100,105,118,105,100, +117,97,108,105,109,112,111,115,115,105,98,108,101,109,117,108,116,105,109,101, +100,105,97,97,108,109,111,115,116,32,97,108,108,112,120,32,115,111,108,105,100, +32,35,97,112,97,114,116,32,102,114,111,109,115,117,98,106,101,99,116,32,116,111, +105,110,32,69,110,103,108,105,115,104,99,114,105,116,105,99,105,122,101,100,101, +120,99,101,112,116,32,102,111,114,103,117,105,100,101,108,105,110,101,115,111, +114,105,103,105,110,97,108,108,121,114,101,109,97,114,107,97,98,108,101,116,104, +101,32,115,101,99,111,110,100,104,50,32,99,108,97,115,115,61,34,60,97,32,116,105 +,116,108,101,61,34,40,105,110,99,108,117,100,105,110,103,112,97,114,97,109,101, +116,101,114,115,112,114,111,104,105,98,105,116,101,100,61,32,34,104,116,116,112, +58,47,47,100,105,99,116,105,111,110,97,114,121,112,101,114,99,101,112,116,105, +111,110,114,101,118,111,108,117,116,105,111,110,102,111,117,110,100,97,116,105, +111,110,112,120,59,104,101,105,103,104,116,58,115,117,99,99,101,115,115,102,117, +108,115,117,112,112,111,114,116,101,114,115,109,105,108,108,101,110,110,105,117, +109,104,105,115,32,102,97,116,104,101,114,116,104,101,32,38,113,117,111,116,59, +110,111,45,114,101,112,101,97,116,59,99,111,109,109,101,114,99,105,97,108,105, +110,100,117,115,116,114,105,97,108,101,110,99,111,117,114,97,103,101,100,97,109, +111,117,110,116,32,111,102,32,117,110,111,102,102,105,99,105,97,108,101,102,102, +105,99,105,101,110,99,121,82,101,102,101,114,101,110,99,101,115,99,111,111,114, +100,105,110,97,116,101,100,105,115,99,108,97,105,109,101,114,101,120,112,101,100 +,105,116,105,111,110,100,101,118,101,108,111,112,105,110,103,99,97,108,99,117, +108,97,116,101,100,115,105,109,112,108,105,102,105,101,100,108,101,103,105,116, +105,109,97,116,101,115,117,98,115,116,114,105,110,103,40,48,34,32,99,108,97,115, +115,61,34,99,111,109,112,108,101,116,101,108,121,105,108,108,117,115,116,114,97, +116,101,102,105,118,101,32,121,101,97,114,115,105,110,115,116,114,117,109,101, +110,116,80,117,98,108,105,115,104,105,110,103,49,34,32,99,108,97,115,115,61,34, +112,115,121,99,104,111,108,111,103,121,99,111,110,102,105,100,101,110,99,101,110 +,117,109,98,101,114,32,111,102,32,97,98,115,101,110,99,101,32,111,102,102,111,99 +,117,115,101,100,32,111,110,106,111,105,110,101,100,32,116,104,101,115,116,114, +117,99,116,117,114,101,115,112,114,101,118,105,111,117,115,108,121,62,60,47,105, +102,114,97,109,101,62,111,110,99,101,32,97,103,97,105,110,98,117,116,32,114,97, +116,104,101,114,105,109,109,105,103,114,97,110,116,115,111,102,32,99,111,117,114 +,115,101,44,97,32,103,114,111,117,112,32,111,102,76,105,116,101,114,97,116,117, +114,101,85,110,108,105,107,101,32,116,104,101,60,47,97,62,38,110,98,115,112,59, +10,102,117,110,99,116,105,111,110,32,105,116,32,119,97,115,32,116,104,101,67,111 +,110,118,101,110,116,105,111,110,97,117,116,111,109,111,98,105,108,101,80,114, +111,116,101,115,116,97,110,116,97,103,103,114,101,115,115,105,118,101,97,102,116 +,101,114,32,116,104,101,32,83,105,109,105,108,97,114,108,121,44,34,32,47,62,60, +47,100,105,118,62,99,111,108,108,101,99,116,105,111,110,13,10,102,117,110,99,116 +,105,111,110,118,105,115,105,98,105,108,105,116,121,116,104,101,32,117,115,101, +32,111,102,118,111,108,117,110,116,101,101,114,115,97,116,116,114,97,99,116,105, +111,110,117,110,100,101,114,32,116,104,101,32,116,104,114,101,97,116,101,110,101 +,100,42,60,33,91,67,68,65,84,65,91,105,109,112,111,114,116,97,110,99,101,105,110 +,32,103,101,110,101,114,97,108,116,104,101,32,108,97,116,116,101,114,60,47,102, +111,114,109,62,10,60,47,46,105,110,100,101,120,79,102,40,39,105,32,61,32,48,59, +32,105,32,60,100,105,102,102,101,114,101,110,99,101,100,101,118,111,116,101,100, +32,116,111,116,114,97,100,105,116,105,111,110,115,115,101,97,114,99,104,32,102, +111,114,117,108,116,105,109,97,116,101,108,121,116,111,117,114,110,97,109,101, +110,116,97,116,116,114,105,98,117,116,101,115,115,111,45,99,97,108,108,101,100, +32,125,10,60,47,115,116,121,108,101,62,101,118,97,108,117,97,116,105,111,110,101 +,109,112,104,97,115,105,122,101,100,97,99,99,101,115,115,105,98,108,101,60,47, +115,101,99,116,105,111,110,62,115,117,99,99,101,115,115,105,111,110,97,108,111, +110,103,32,119,105,116,104,77,101,97,110,119,104,105,108,101,44,105,110,100,117, +115,116,114,105,101,115,60,47,97,62,60,98,114,32,47,62,104,97,115,32,98,101,99, +111,109,101,97,115,112,101,99,116,115,32,111,102,84,101,108,101,118,105,115,105, +111,110,115,117,102,102,105,99,105,101,110,116,98,97,115,107,101,116,98,97,108, +108,98,111,116,104,32,115,105,100,101,115,99,111,110,116,105,110,117,105,110,103 +,97,110,32,97,114,116,105,99,108,101,60,105,109,103,32,97,108,116,61,34,97,100, +118,101,110,116,117,114,101,115,104,105,115,32,109,111,116,104,101,114,109,97, +110,99,104,101,115,116,101,114,112,114,105,110,99,105,112,108,101,115,112,97,114 +,116,105,99,117,108,97,114,99,111,109,109,101,110,116,97,114,121,101,102,102,101 +,99,116,115,32,111,102,100,101,99,105,100,101,100,32,116,111,34,62,60,115,116, +114,111,110,103,62,112,117,98,108,105,115,104,101,114,115,74,111,117,114,110,97, +108,32,111,102,100,105,102,102,105,99,117,108,116,121,102,97,99,105,108,105,116, +97,116,101,97,99,99,101,112,116,97,98,108,101,115,116,121,108,101,46,99,115,115, +34,9,102,117,110,99,116,105,111,110,32,105,110,110,111,118,97,116,105,111,110,62 +,67,111,112,121,114,105,103,104,116,115,105,116,117,97,116,105,111,110,115,119, +111,117,108,100,32,104,97,118,101,98,117,115,105,110,101,115,115,101,115,68,105, +99,116,105,111,110,97,114,121,115,116,97,116,101,109,101,110,116,115,111,102,116 +,101,110,32,117,115,101,100,112,101,114,115,105,115,116,101,110,116,105,110,32, +74,97,110,117,97,114,121,99,111,109,112,114,105,115,105,110,103,60,47,116,105, +116,108,101,62,10,9,100,105,112,108,111,109,97,116,105,99,99,111,110,116,97,105, +110,105,110,103,112,101,114,102,111,114,109,105,110,103,101,120,116,101,110,115, +105,111,110,115,109,97,121,32,110,111,116,32,98,101,99,111,110,99,101,112,116,32 +,111,102,32,111,110,99,108,105,99,107,61,34,73,116,32,105,115,32,97,108,115,111, +102,105,110,97,110,99,105,97,108,32,109,97,107,105,110,103,32,116,104,101,76,117 +,120,101,109,98,111,117,114,103,97,100,100,105,116,105,111,110,97,108,97,114,101 +,32,99,97,108,108,101,100,101,110,103,97,103,101,100,32,105,110,34,115,99,114, +105,112,116,34,41,59,98,117,116,32,105,116,32,119,97,115,101,108,101,99,116,114, +111,110,105,99,111,110,115,117,98,109,105,116,61,34,10,60,33,45,45,32,69,110,100 +,32,101,108,101,99,116,114,105,99,97,108,111,102,102,105,99,105,97,108,108,121, +115,117,103,103,101,115,116,105,111,110,116,111,112,32,111,102,32,116,104,101, +117,110,108,105,107,101,32,116,104,101,65,117,115,116,114,97,108,105,97,110,79, +114,105,103,105,110,97,108,108,121,114,101,102,101,114,101,110,99,101,115,10,60, +47,104,101,97,100,62,13,10,114,101,99,111,103,110,105,115,101,100,105,110,105, +116,105,97,108,105,122,101,108,105,109,105,116,101,100,32,116,111,65,108,101,120 +,97,110,100,114,105,97,114,101,116,105,114,101,109,101,110,116,65,100,118,101, +110,116,117,114,101,115,102,111,117,114,32,121,101,97,114,115,10,10,38,108,116, +59,33,45,45,32,105,110,99,114,101,97,115,105,110,103,100,101,99,111,114,97,116, +105,111,110,104,51,32,99,108,97,115,115,61,34,111,114,105,103,105,110,115,32,111 +,102,111,98,108,105,103,97,116,105,111,110,114,101,103,117,108,97,116,105,111, +110,99,108,97,115,115,105,102,105,101,100,40,102,117,110,99,116,105,111,110,40, +97,100,118,97,110,116,97,103,101,115,98,101,105,110,103,32,116,104,101,32,104, +105,115,116,111,114,105,97,110,115,60,98,97,115,101,32,104,114,101,102,114,101, +112,101,97,116,101,100,108,121,119,105,108,108,105,110,103,32,116,111,99,111,109 +,112,97,114,97,98,108,101,100,101,115,105,103,110,97,116,101,100,110,111,109,105 +,110,97,116,105,111,110,102,117,110,99,116,105,111,110,97,108,105,110,115,105, +100,101,32,116,104,101,114,101,118,101,108,97,116,105,111,110,101,110,100,32,111 +,102,32,116,104,101,115,32,102,111,114,32,116,104,101,32,97,117,116,104,111,114, +105,122,101,100,114,101,102,117,115,101,100,32,116,111,116,97,107,101,32,112,108 +,97,99,101,97,117,116,111,110,111,109,111,117,115,99,111,109,112,114,111,109,105 +,115,101,112,111,108,105,116,105,99,97,108,32,114,101,115,116,97,117,114,97,110, +116,116,119,111,32,111,102,32,116,104,101,70,101,98,114,117,97,114,121,32,50,113 +,117,97,108,105,116,121,32,111,102,115,119,102,111,98,106,101,99,116,46,117,110, +100,101,114,115,116,97,110,100,110,101,97,114,108,121,32,97,108,108,119,114,105, +116,116,101,110,32,98,121,105,110,116,101,114,118,105,101,119,115,34,32,119,105, +100,116,104,61,34,49,119,105,116,104,100,114,97,119,97,108,102,108,111,97,116,58 +,108,101,102,116,105,115,32,117,115,117,97,108,108,121,99,97,110,100,105,100,97, +116,101,115,110,101,119,115,112,97,112,101,114,115,109,121,115,116,101,114,105, +111,117,115,68,101,112,97,114,116,109,101,110,116,98,101,115,116,32,107,110,111, +119,110,112,97,114,108,105,97,109,101,110,116,115,117,112,112,114,101,115,115, +101,100,99,111,110,118,101,110,105,101,110,116,114,101,109,101,109,98,101,114, +101,100,100,105,102,102,101,114,101,110,116,32,115,121,115,116,101,109,97,116, +105,99,104,97,115,32,108,101,100,32,116,111,112,114,111,112,97,103,97,110,100,97 +,99,111,110,116,114,111,108,108,101,100,105,110,102,108,117,101,110,99,101,115, +99,101,114,101,109,111,110,105,97,108,112,114,111,99,108,97,105,109,101,100,80, +114,111,116,101,99,116,105,111,110,108,105,32,99,108,97,115,115,61,34,83,99,105, +101,110,116,105,102,105,99,99,108,97,115,115,61,34,110,111,45,116,114,97,100,101 +,109,97,114,107,115,109,111,114,101,32,116,104,97,110,32,119,105,100,101,115,112 +,114,101,97,100,76,105,98,101,114,97,116,105,111,110,116,111,111,107,32,112,108, +97,99,101,100,97,121,32,111,102,32,116,104,101,97,115,32,108,111,110,103,32,97, +115,105,109,112,114,105,115,111,110,101,100,65,100,100,105,116,105,111,110,97, +108,10,60,104,101,97,100,62,10,60,109,76,97,98,111,114,97,116,111,114,121,78,111 +,118,101,109,98,101,114,32,50,101,120,99,101,112,116,105,111,110,115,73,110,100, +117,115,116,114,105,97,108,118,97,114,105,101,116,121,32,111,102,102,108,111,97, +116,58,32,108,101,102,68,117,114,105,110,103,32,116,104,101,97,115,115,101,115, +115,109,101,110,116,104,97,118,101,32,98,101,101,110,32,100,101,97,108,115,32, +119,105,116,104,83,116,97,116,105,115,116,105,99,115,111,99,99,117,114,114,101, +110,99,101,47,117,108,62,60,47,100,105,118,62,99,108,101,97,114,102,105,120,34, +62,116,104,101,32,112,117,98,108,105,99,109,97,110,121,32,121,101,97,114,115,119 +,104,105,99,104,32,119,101,114,101,111,118,101,114,32,116,105,109,101,44,115,121 +,110,111,110,121,109,111,117,115,99,111,110,116,101,110,116,34,62,10,112,114,101 +,115,117,109,97,98,108,121,104,105,115,32,102,97,109,105,108,121,117,115,101,114 +,65,103,101,110,116,46,117,110,101,120,112,101,99,116,101,100,105,110,99,108,117 +,100,105,110,103,32,99,104,97,108,108,101,110,103,101,100,97,32,109,105,110,111, +114,105,116,121,117,110,100,101,102,105,110,101,100,34,98,101,108,111,110,103, +115,32,116,111,116,97,107,101,110,32,102,114,111,109,105,110,32,79,99,116,111,98 +,101,114,112,111,115,105,116,105,111,110,58,32,115,97,105,100,32,116,111,32,98, +101,114,101,108,105,103,105,111,117,115,32,70,101,100,101,114,97,116,105,111,110 +,32,114,111,119,115,112,97,110,61,34,111,110,108,121,32,97,32,102,101,119,109, +101,97,110,116,32,116,104,97,116,108,101,100,32,116,111,32,116,104,101,45,45,62, +13,10,60,100,105,118,32,60,102,105,101,108,100,115,101,116,62,65,114,99,104,98, +105,115,104,111,112,32,99,108,97,115,115,61,34,110,111,98,101,105,110,103,32,117 +,115,101,100,97,112,112,114,111,97,99,104,101,115,112,114,105,118,105,108,101, +103,101,115,110,111,115,99,114,105,112,116,62,10,114,101,115,117,108,116,115,32, +105,110,109,97,121,32,98,101,32,116,104,101,69,97,115,116,101,114,32,101,103,103 +,109,101,99,104,97,110,105,115,109,115,114,101,97,115,111,110,97,98,108,101,80, +111,112,117,108,97,116,105,111,110,67,111,108,108,101,99,116,105,111,110,115,101 +,108,101,99,116,101,100,34,62,110,111,115,99,114,105,112,116,62,13,47,105,110, +100,101,120,46,112,104,112,97,114,114,105,118,97,108,32,111,102,45,106,115,115, +100,107,39,41,41,59,109,97,110,97,103,101,100,32,116,111,105,110,99,111,109,112, +108,101,116,101,99,97,115,117,97,108,116,105,101,115,99,111,109,112,108,101,116, +105,111,110,67,104,114,105,115,116,105,97,110,115,83,101,112,116,101,109,98,101, +114,32,97,114,105,116,104,109,101,116,105,99,112,114,111,99,101,100,117,114,101, +115,109,105,103,104,116,32,104,97,118,101,80,114,111,100,117,99,116,105,111,110, +105,116,32,97,112,112,101,97,114,115,80,104,105,108,111,115,111,112,104,121,102, +114,105,101,110,100,115,104,105,112,108,101,97,100,105,110,103,32,116,111,103, +105,118,105,110,103,32,116,104,101,116,111,119,97,114,100,32,116,104,101,103,117 +,97,114,97,110,116,101,101,100,100,111,99,117,109,101,110,116,101,100,99,111,108 +,111,114,58,35,48,48,48,118,105,100,101,111,32,103,97,109,101,99,111,109,109,105 +,115,115,105,111,110,114,101,102,108,101,99,116,105,110,103,99,104,97,110,103, +101,32,116,104,101,97,115,115,111,99,105,97,116,101,100,115,97,110,115,45,115, +101,114,105,102,111,110,107,101,121,112,114,101,115,115,59,32,112,97,100,100,105 +,110,103,58,72,101,32,119,97,115,32,116,104,101,117,110,100,101,114,108,121,105, +110,103,116,121,112,105,99,97,108,108,121,32,44,32,97,110,100,32,116,104,101,32, +115,114,99,69,108,101,109,101,110,116,115,117,99,99,101,115,115,105,118,101,115, +105,110,99,101,32,116,104,101,32,115,104,111,117,108,100,32,98,101,32,110,101, +116,119,111,114,107,105,110,103,97,99,99,111,117,110,116,105,110,103,117,115,101 +,32,111,102,32,116,104,101,108,111,119,101,114,32,116,104,97,110,115,104,111,119 +,115,32,116,104,97,116,60,47,115,112,97,110,62,10,9,9,99,111,109,112,108,97,105, +110,116,115,99,111,110,116,105,110,117,111,117,115,113,117,97,110,116,105,116, +105,101,115,97,115,116,114,111,110,111,109,101,114,104,101,32,100,105,100,32,110 +,111,116,100,117,101,32,116,111,32,105,116,115,97,112,112,108,105,101,100,32,116 +,111,97,110,32,97,118,101,114,97,103,101,101,102,102,111,114,116,115,32,116,111, +116,104,101,32,102,117,116,117,114,101,97,116,116,101,109,112,116,32,116,111,84, +104,101,114,101,102,111,114,101,44,99,97,112,97,98,105,108,105,116,121,82,101, +112,117,98,108,105,99,97,110,119,97,115,32,102,111,114,109,101,100,69,108,101,99 +,116,114,111,110,105,99,107,105,108,111,109,101,116,101,114,115,99,104,97,108, +108,101,110,103,101,115,112,117,98,108,105,115,104,105,110,103,116,104,101,32, +102,111,114,109,101,114,105,110,100,105,103,101,110,111,117,115,100,105,114,101, +99,116,105,111,110,115,115,117,98,115,105,100,105,97,114,121,99,111,110,115,112, +105,114,97,99,121,100,101,116,97,105,108,115,32,111,102,97,110,100,32,105,110,32 +,116,104,101,97,102,102,111,114,100,97,98,108,101,115,117,98,115,116,97,110,99, +101,115,114,101,97,115,111,110,32,102,111,114,99,111,110,118,101,110,116,105,111 +,110,105,116,101,109,116,121,112,101,61,34,97,98,115,111,108,117,116,101,108,121 +,115,117,112,112,111,115,101,100,108,121,114,101,109,97,105,110,101,100,32,97,97 +,116,116,114,97,99,116,105,118,101,116,114,97,118,101,108,108,105,110,103,115, +101,112,97,114,97,116,101,108,121,102,111,99,117,115,101,115,32,111,110,101,108, +101,109,101,110,116,97,114,121,97,112,112,108,105,99,97,98,108,101,102,111,117, +110,100,32,116,104,97,116,115,116,121,108,101,115,104,101,101,116,109,97,110,117 +,115,99,114,105,112,116,115,116,97,110,100,115,32,102,111,114,32,110,111,45,114, +101,112,101,97,116,40,115,111,109,101,116,105,109,101,115,67,111,109,109,101,114 +,99,105,97,108,105,110,32,65,109,101,114,105,99,97,117,110,100,101,114,116,97, +107,101,110,113,117,97,114,116,101,114,32,111,102,97,110,32,101,120,97,109,112, +108,101,112,101,114,115,111,110,97,108,108,121,105,110,100,101,120,46,112,104, +112,63,60,47,98,117,116,116,111,110,62,10,112,101,114,99,101,110,116,97,103,101, +98,101,115,116,45,107,110,111,119,110,99,114,101,97,116,105,110,103,32,97,34,32, +100,105,114,61,34,108,116,114,76,105,101,117,116,101,110,97,110,116,10,60,100, +105,118,32,105,100,61,34,116,104,101,121,32,119,111,117,108,100,97,98,105,108, +105,116,121,32,111,102,109,97,100,101,32,117,112,32,111,102,110,111,116,101,100, +32,116,104,97,116,99,108,101,97,114,32,116,104,97,116,97,114,103,117,101,32,116, +104,97,116,116,111,32,97,110,111,116,104,101,114,99,104,105,108,100,114,101,110, +39,115,112,117,114,112,111,115,101,32,111,102,102,111,114,109,117,108,97,116,101 +,100,98,97,115,101,100,32,117,112,111,110,116,104,101,32,114,101,103,105,111,110 +,115,117,98,106,101,99,116,32,111,102,112,97,115,115,101,110,103,101,114,115,112 +,111,115,115,101,115,115,105,111,110,46,10,10,73,110,32,116,104,101,32,66,101, +102,111,114,101,32,116,104,101,97,102,116,101,114,119,97,114,100,115,99,117,114, +114,101,110,116,108,121,32,97,99,114,111,115,115,32,116,104,101,115,99,105,101, +110,116,105,102,105,99,99,111,109,109,117,110,105,116,121,46,99,97,112,105,116, +97,108,105,115,109,105,110,32,71,101,114,109,97,110,121,114,105,103,104,116,45, +119,105,110,103,116,104,101,32,115,121,115,116,101,109,83,111,99,105,101,116,121 +,32,111,102,112,111,108,105,116,105,99,105,97,110,100,105,114,101,99,116,105,111 +,110,58,119,101,110,116,32,111,110,32,116,111,114,101,109,111,118,97,108,32,111, +102,32,78,101,119,32,89,111,114,107,32,97,112,97,114,116,109,101,110,116,115,105 +,110,100,105,99,97,116,105,111,110,100,117,114,105,110,103,32,116,104,101,117, +110,108,101,115,115,32,116,104,101,104,105,115,116,111,114,105,99,97,108,104,97, +100,32,98,101,101,110,32,97,100,101,102,105,110,105,116,105,118,101,105,110,103, +114,101,100,105,101,110,116,97,116,116,101,110,100,97,110,99,101,67,101,110,116, +101,114,32,102,111,114,112,114,111,109,105,110,101,110,99,101,114,101,97,100,121 +,83,116,97,116,101,115,116,114,97,116,101,103,105,101,115,98,117,116,32,105,110, +32,116,104,101,97,115,32,112,97,114,116,32,111,102,99,111,110,115,116,105,116, +117,116,101,99,108,97,105,109,32,116,104,97,116,108,97,98,111,114,97,116,111,114 +,121,99,111,109,112,97,116,105,98,108,101,102,97,105,108,117,114,101,32,111,102, +44,32,115,117,99,104,32,97,115,32,98,101,103,97,110,32,119,105,116,104,117,115, +105,110,103,32,116,104,101,32,116,111,32,112,114,111,118,105,100,101,102,101,97, +116,117,114,101,32,111,102,102,114,111,109,32,119,104,105,99,104,47,34,32,99,108 +,97,115,115,61,34,103,101,111,108,111,103,105,99,97,108,115,101,118,101,114,97, +108,32,111,102,100,101,108,105,98,101,114,97,116,101,105,109,112,111,114,116,97, +110,116,32,104,111,108,100,115,32,116,104,97,116,105,110,103,38,113,117,111,116, +59,32,118,97,108,105,103,110,61,116,111,112,116,104,101,32,71,101,114,109,97,110 +,111,117,116,115,105,100,101,32,111,102,110,101,103,111,116,105,97,116,101,100, +104,105,115,32,99,97,114,101,101,114,115,101,112,97,114,97,116,105,111,110,105, +100,61,34,115,101,97,114,99,104,119,97,115,32,99,97,108,108,101,100,116,104,101, +32,102,111,117,114,116,104,114,101,99,114,101,97,116,105,111,110,111,116,104,101 +,114,32,116,104,97,110,112,114,101,118,101,110,116,105,111,110,119,104,105,108, +101,32,116,104,101,32,101,100,117,99,97,116,105,111,110,44,99,111,110,110,101,99 +,116,105,110,103,97,99,99,117,114,97,116,101,108,121,119,101,114,101,32,98,117, +105,108,116,119,97,115,32,107,105,108,108,101,100,97,103,114,101,101,109,101,110 +,116,115,109,117,99,104,32,109,111,114,101,32,68,117,101,32,116,111,32,116,104, +101,119,105,100,116,104,58,32,49,48,48,115,111,109,101,32,111,116,104,101,114,75 +,105,110,103,100,111,109,32,111,102,116,104,101,32,101,110,116,105,114,101,102, +97,109,111,117,115,32,102,111,114,116,111,32,99,111,110,110,101,99,116,111,98, +106,101,99,116,105,118,101,115,116,104,101,32,70,114,101,110,99,104,112,101,111, +112,108,101,32,97,110,100,102,101,97,116,117,114,101,100,34,62,105,115,32,115,97 +,105,100,32,116,111,115,116,114,117,99,116,117,114,97,108,114,101,102,101,114, +101,110,100,117,109,109,111,115,116,32,111,102,116,101,110,97,32,115,101,112,97, +114,97,116,101,45,62,10,60,100,105,118,32,105,100,32,79,102,102,105,99,105,97, +108,32,119,111,114,108,100,119,105,100,101,46,97,114,105,97,45,108,97,98,101,108 +,116,104,101,32,112,108,97,110,101,116,97,110,100,32,105,116,32,119,97,115,100, +34,32,118,97,108,117,101,61,34,108,111,111,107,105,110,103,32,97,116,98,101,110, +101,102,105,99,105,97,108,97,114,101,32,105,110,32,116,104,101,109,111,110,105, +116,111,114,105,110,103,114,101,112,111,114,116,101,100,108,121,116,104,101,32, +109,111,100,101,114,110,119,111,114,107,105,110,103,32,111,110,97,108,108,111, +119,101,100,32,116,111,119,104,101,114,101,32,116,104,101,32,105,110,110,111,118 +,97,116,105,118,101,60,47,97,62,60,47,100,105,118,62,115,111,117,110,100,116,114 +,97,99,107,115,101,97,114,99,104,70,111,114,109,116,101,110,100,32,116,111,32,98 +,101,105,110,112,117,116,32,105,100,61,34,111,112,101,110,105,110,103,32,111,102 +,114,101,115,116,114,105,99,116,101,100,97,100,111,112,116,101,100,32,98,121,97, +100,100,114,101,115,115,105,110,103,116,104,101,111,108,111,103,105,97,110,109, +101,116,104,111,100,115,32,111,102,118,97,114,105,97,110,116,32,111,102,67,104, +114,105,115,116,105,97,110,32,118,101,114,121,32,108,97,114,103,101,97,117,116, +111,109,111,116,105,118,101,98,121,32,102,97,114,32,116,104,101,114,97,110,103, +101,32,102,114,111,109,112,117,114,115,117,105,116,32,111,102,102,111,108,108, +111,119,32,116,104,101,98,114,111,117,103,104,116,32,116,111,105,110,32,69,110, +103,108,97,110,100,97,103,114,101,101,32,116,104,97,116,97,99,99,117,115,101,100 +,32,111,102,99,111,109,101,115,32,102,114,111,109,112,114,101,118,101,110,116, +105,110,103,100,105,118,32,115,116,121,108,101,61,104,105,115,32,111,114,32,104, +101,114,116,114,101,109,101,110,100,111,117,115,102,114,101,101,100,111,109,32, +111,102,99,111,110,99,101,114,110,105,110,103,48,32,49,101,109,32,49,101,109,59, +66,97,115,107,101,116,98,97,108,108,47,115,116,121,108,101,46,99,115,115,97,110, +32,101,97,114,108,105,101,114,101,118,101,110,32,97,102,116,101,114,47,34,32,116 +,105,116,108,101,61,34,46,99,111,109,47,105,110,100,101,120,116,97,107,105,110, +103,32,116,104,101,112,105,116,116,115,98,117,114,103,104,99,111,110,116,101,110 +,116,34,62,13,60,115,99,114,105,112,116,62,40,102,116,117,114,110,101,100,32,111 +,117,116,104,97,118,105,110,103,32,116,104,101,60,47,115,112,97,110,62,13,10,32, +111,99,99,97,115,105,111,110,97,108,98,101,99,97,117,115,101,32,105,116,115,116, +97,114,116,101,100,32,116,111,112,104,121,115,105,99,97,108,108,121,62,60,47,100 +,105,118,62,10,32,32,99,114,101,97,116,101,100,32,98,121,67,117,114,114,101,110, +116,108,121,44,32,98,103,99,111,108,111,114,61,34,116,97,98,105,110,100,101,120, +61,34,100,105,115,97,115,116,114,111,117,115,65,110,97,108,121,116,105,99,115,32 +,97,108,115,111,32,104,97,115,32,97,62,60,100,105,118,32,105,100,61,34,60,47,115 +,116,121,108,101,62,10,60,99,97,108,108,101,100,32,102,111,114,115,105,110,103, +101,114,32,97,110,100,46,115,114,99,32,61,32,34,47,47,118,105,111,108,97,116,105 +,111,110,115,116,104,105,115,32,112,111,105,110,116,99,111,110,115,116,97,110, +116,108,121,105,115,32,108,111,99,97,116,101,100,114,101,99,111,114,100,105,110, +103,115,100,32,102,114,111,109,32,116,104,101,110,101,100,101,114,108,97,110,100 +,115,112,111,114,116,117,103,117,195,170,115,215,162,215,145,215,168,215,153,215 +,170,217,129,216,167,216,177,216,179,219,140,100,101,115,97,114,114,111,108,108, +111,99,111,109,101,110,116,97,114,105,111,101,100,117,99,97,99,105,195,179,110, +115,101,112,116,105,101,109,98,114,101,114,101,103,105,115,116,114,97,100,111, +100,105,114,101,99,99,105,195,179,110,117,98,105,99,97,99,105,195,179,110,112, +117,98,108,105,99,105,100,97,100,114,101,115,112,117,101,115,116,97,115,114,101, +115,117,108,116,97,100,111,115,105,109,112,111,114,116,97,110,116,101,114,101, +115,101,114,118,97,100,111,115,97,114,116,195,173,99,117,108,111,115,100,105,102 +,101,114,101,110,116,101,115,115,105,103,117,105,101,110,116,101,115,114,101,112 +,195,186,98,108,105,99,97,115,105,116,117,97,99,105,195,179,110,109,105,110,105, +115,116,101,114,105,111,112,114,105,118,97,99,105,100,97,100,100,105,114,101,99, +116,111,114,105,111,102,111,114,109,97,99,105,195,179,110,112,111,98,108,97,99, +105,195,179,110,112,114,101,115,105,100,101,110,116,101,99,111,110,116,101,110, +105,100,111,115,97,99,99,101,115,111,114,105,111,115,116,101,99,104,110,111,114, +97,116,105,112,101,114,115,111,110,97,108,101,115,99,97,116,101,103,111,114,195, +173,97,101,115,112,101,99,105,97,108,101,115,100,105,115,112,111,110,105,98,108, +101,97,99,116,117,97,108,105,100,97,100,114,101,102,101,114,101,110,99,105,97, +118,97,108,108,97,100,111,108,105,100,98,105,98,108,105,111,116,101,99,97,114, +101,108,97,99,105,111,110,101,115,99,97,108,101,110,100,97,114,105,111,112,111, +108,195,173,116,105,99,97,115,97,110,116,101,114,105,111,114,101,115,100,111,99, +117,109,101,110,116,111,115,110,97,116,117,114,97,108,101,122,97,109,97,116,101, +114,105,97,108,101,115,100,105,102,101,114,101,110,99,105,97,101,99,111,110,195, +179,109,105,99,97,116,114,97,110,115,112,111,114,116,101,114,111,100,114,195,173 +,103,117,101,122,112,97,114,116,105,99,105,112,97,114,101,110,99,117,101,110,116 +,114,97,110,100,105,115,99,117,115,105,195,179,110,101,115,116,114,117,99,116, +117,114,97,102,117,110,100,97,99,105,195,179,110,102,114,101,99,117,101,110,116, +101,115,112,101,114,109,97,110,101,110,116,101,116,111,116,97,108,109,101,110, +116,101,208,188,208,190,208,182,208,189,208,190,208,177,209,131,208,180,208,181, +209,130,208,188,208,190,208,182,208,181,209,130,208,178,209,128,208,181,208,188, +209,143,209,130,208,176,208,186,208,182,208,181,209,135,209,130,208,190,208,177, +209,139,208,177,208,190,208,187,208,181,208,181,208,190,209,135,208,181,208,189, +209,140,209,141,209,130,208,190,208,179,208,190,208,186,208,190,208,179,208,180, +208,176,208,191,208,190,209,129,208,187,208,181,208,178,209,129,208,181,208,179, +208,190,209,129,208,176,208,185,209,130,208,181,209,135,208,181,209,128,208,181, +208,183,208,188,208,190,208,179,209,131,209,130,209,129,208,176,208,185,209,130, +208,176,208,182,208,184,208,183,208,189,208,184,208,188,208,181,208,182,208,180, +209,131,208,177,209,131,208,180,209,131,209,130,208,159,208,190,208,184,209,129, +208,186,208,183,208,180,208,181,209,129,209,140,208,178,208,184,208,180,208,181, +208,190,209,129,208,178,209,143,208,183,208,184,208,189,209,131,208,182,208,189, +208,190,209,129,208,178,208,190,208,181,208,185,208,187,209,142,208,180,208,181, +208,185,208,191,208,190,209,128,208,189,208,190,208,188,208,189,208,190,208,179, +208,190,208,180,208,181,209,130,208,181,208,185,209,129,208,178,208,190,208,184, +209,133,208,191,209,128,208,176,208,178,208,176,209,130,208,176,208,186,208,190, +208,185,208,188,208,181,209,129,209,130,208,190,208,184,208,188,208,181,208,181, +209,130,208,182,208,184,208,183,208,189,209,140,208,190,208,180,208,189,208,190, +208,185,208,187,209,131,209,135,209,136,208,181,208,191,208,181,209,128,208,181, +208,180,209,135,208,176,209,129,209,130,208,184,209,135,208,176,209,129,209,130, +209,140,209,128,208,176,208,177,208,190,209,130,208,189,208,190,208,178,209,139, +209,133,208,191,209,128,208,176,208,178,208,190,209,129,208,190,208,177,208,190, +208,185,208,191,208,190,209,130,208,190,208,188,208,188,208,181,208,189,208,181, +208,181,209,135,208,184,209,129,208,187,208,181,208,189,208,190,208,178,209,139, +208,181,209,131,209,129,208,187,209,131,208,179,208,190,208,186,208,190,208,187, +208,190,208,189,208,176,208,183,208,176,208,180,209,130,208,176,208,186,208,190, +208,181,209,130,208,190,208,179,208,180,208,176,208,191,208,190,209,135,209,130, +208,184,208,159,208,190,209,129,208,187,208,181,209,130,208,176,208,186,208,184, +208,181,208,189,208,190,208,178,209,139,208,185,209,129,209,130,208,190,208,184, +209,130,209,130,208,176,208,186,208,184,209,133,209,129,209,128,208,176,208,183, +209,131,208,161,208,176,208,189,208,186,209,130,209,132,208,190,209,128,209,131, +208,188,208,154,208,190,208,179,208,180,208,176,208,186,208,189,208,184,208,179, +208,184,209,129,208,187,208,190,208,178,208,176,208,189,208,176,209,136,208,181, +208,185,208,189,208,176,208,185,209,130,208,184,209,129,208,178,208,190,208,184, +208,188,209,129,208,178,209,143,208,183,209,140,208,187,209,142,208,177,208,190, +208,185,209,135,208,176,209,129,209,130,208,190,209,129,209,128,208,181,208,180, +208,184,208,154,209,128,208,190,208,188,208,181,208,164,208,190,209,128,209,131, +208,188,209,128,209,139,208,189,208,186,208,181,209,129,209,130,208,176,208,187, +208,184,208,191,208,190,208,184,209,129,208,186,209,130,209,139,209,129,209,143, +209,135,208,188,208,181,209,129,209,143,209,134,209,134,208,181,208,189,209,130, +209,128,209,130,209,128,209,131,208,180,208,176,209,129,208,176,208,188,209,139, +209,133,209,128,209,139,208,189,208,186,208,176,208,157,208,190,208,178,209,139, +208,185,209,135,208,176,209,129,208,190,208,178,208,188,208,181,209,129,209,130, +208,176,209,132,208,184,208,187,209,140,208,188,208,188,208,176,209,128,209,130, +208,176,209,129,209,130,209,128,208,176,208,189,208,188,208,181,209,129,209,130, +208,181,209,130,208,181,208,186,209,129,209,130,208,189,208,176,209,136,208,184, +209,133,208,188,208,184,208,189,209,131,209,130,208,184,208,188,208,181,208,189, +208,184,208,184,208,188,208,181,209,142,209,130,208,189,208,190,208,188,208,181, +209,128,208,179,208,190,209,128,208,190,208,180,209,129,208,176,208,188,208,190, +208,188,209,141,209,130,208,190,208,188,209,131,208,186,208,190,208,189,209,134, +208,181,209,129,208,178,208,190,208,181,208,188,208,186,208,176,208,186,208,190, +208,185,208,144,209,128,209,133,208,184,208,178,217,133,217,134,216,170,216,175, +217,137,216,165,216,177,216,179,216,167,217,132,216,177,216,179,216,167,217,132, +216,169,216,167,217,132,216,185,216,167,217,133,217,131,216,170,216,168,217,135, +216,167,216,168,216,177,216,167,217,133,216,172,216,167,217,132,217,138,217,136, +217,133,216,167,217,132,216,181,217,136,216,177,216,172,216,175,217,138,216,175, +216,169,216,167,217,132,216,185,216,182,217,136,216,165,216,182,216,167,217,129, +216,169,216,167,217,132,217,130,216,179,217,133,216,167,217,132,216,185,216,167, +216,168,216,170,216,173,217,133,217,138,217,132,217,133,217,132,217,129,216,167, +216,170,217,133,217,132,216,170,217,130,217,137,216,170,216,185,216,175,217,138, +217,132,216,167,217,132,216,180,216,185,216,177,216,163,216,174,216,168,216,167, +216,177,216,170,216,183,217,136,217,138,216,177,216,185,217,132,217,138,217,131, +217,133,216,165,216,177,217,129,216,167,217,130,216,183,217,132,216,168,216,167, +216,170,216,167,217,132,217,132,216,186,216,169,216,170,216,177,216,170,217,138, +216,168,216,167,217,132,217,134,216,167,216,179,216,167,217,132,216,180,217,138, +216,174,217,133,217,134,216,170,216,175,217,138,216,167,217,132,216,185,216,177, +216,168,216,167,217,132,217,130,216,181,216,181,216,167,217,129,217,132,216,167, +217,133,216,185,217,132,217,138,217,135,216,167,216,170,216,173,216,175,217,138, +216,171,216,167,217,132,217,132,217,135,217,133,216,167,217,132,216,185,217,133, +217,132,217,133,217,131,216,170,216,168,216,169,217,138,217,133,217,131,217,134, +217,131,216,167,217,132,216,183,217,129,217,132,217,129,217,138,216,175,217,138, +217,136,216,165,216,175,216,167,216,177,216,169,216,170,216,167,216,177,217,138, +216,174,216,167,217,132,216,181,216,173,216,169,216,170,216,179,216,172,217,138, +217,132,216,167,217,132,217,136,217,130,216,170,216,185,217,134,216,175,217,133, +216,167,217,133,216,175,217,138,217,134,216,169,216,170,216,181,217,133,217,138, +217,133,216,163,216,177,216,180,217,138,217,129,216,167,217,132,216,176,217,138, +217,134,216,185,216,177,216,168,217,138,216,169,216,168,217,136,216,167,216,168, +216,169,216,163,217,132,216,185,216,167,216,168,216,167,217,132,216,179,217,129, +216,177,217,133,216,180,216,167,217,131,217,132,216,170,216,185,216,167,217,132, +217,137,216,167,217,132,216,163,217,136,217,132,216,167,217,132,216,179,217,134, +216,169,216,172,216,167,217,133,216,185,216,169,216,167,217,132,216,181,216,173, +217,129,216,167,217,132,216,175,217,138,217,134,217,131,217,132,217,133,216,167, +216,170,216,167,217,132,216,174,216,167,216,181,216,167,217,132,217,133,217,132, +217,129,216,163,216,185,216,182,216,167,216,161,217,131,216,170,216,167,216,168, +216,169,216,167,217,132,216,174,217,138,216,177,216,177,216,179,216,167,216,166, +217,132,216,167,217,132,217,130,217,132,216,168,216,167,217,132,216,163,216,175, +216,168,217,133,217,130,216,167,216,183,216,185,217,133,216,177,216,167,216,179, +217,132,217,133,217,134,216,183,217,130,216,169,216,167,217,132,217,131,216,170, +216,168,216,167,217,132,216,177,216,172,217,132,216,167,216,180,216,170,216,177, +217,131,216,167,217,132,217,130,216,175,217,133,217,138,216,185,216,183,217,138, +217,131,115,66,121,84,97,103,78,97,109,101,40,46,106,112,103,34,32,97,108,116,61 +,34,49,112,120,32,115,111,108,105,100,32,35,46,103,105,102,34,32,97,108,116,61, +34,116,114,97,110,115,112,97,114,101,110,116,105,110,102,111,114,109,97,116,105, +111,110,97,112,112,108,105,99,97,116,105,111,110,34,32,111,110,99,108,105,99,107 +,61,34,101,115,116,97,98,108,105,115,104,101,100,97,100,118,101,114,116,105,115, +105,110,103,46,112,110,103,34,32,97,108,116,61,34,101,110,118,105,114,111,110, +109,101,110,116,112,101,114,102,111,114,109,97,110,99,101,97,112,112,114,111,112 +,114,105,97,116,101,38,97,109,112,59,109,100,97,115,104,59,105,109,109,101,100, +105,97,116,101,108,121,60,47,115,116,114,111,110,103,62,60,47,114,97,116,104,101 +,114,32,116,104,97,110,116,101,109,112,101,114,97,116,117,114,101,100,101,118, +101,108,111,112,109,101,110,116,99,111,109,112,101,116,105,116,105,111,110,112, +108,97,99,101,104,111,108,100,101,114,118,105,115,105,98,105,108,105,116,121,58, +99,111,112,121,114,105,103,104,116,34,62,48,34,32,104,101,105,103,104,116,61,34, +101,118,101,110,32,116,104,111,117,103,104,114,101,112,108,97,99,101,109,101,110 +,116,100,101,115,116,105,110,97,116,105,111,110,67,111,114,112,111,114,97,116, +105,111,110,60,117,108,32,99,108,97,115,115,61,34,65,115,115,111,99,105,97,116, +105,111,110,105,110,100,105,118,105,100,117,97,108,115,112,101,114,115,112,101, +99,116,105,118,101,115,101,116,84,105,109,101,111,117,116,40,117,114,108,40,104, +116,116,112,58,47,47,109,97,116,104,101,109,97,116,105,99,115,109,97,114,103,105 +,110,45,116,111,112,58,101,118,101,110,116,117,97,108,108,121,32,100,101,115,99, +114,105,112,116,105,111,110,41,32,110,111,45,114,101,112,101,97,116,99,111,108, +108,101,99,116,105,111,110,115,46,74,80,71,124,116,104,117,109,98,124,112,97,114 +,116,105,99,105,112,97,116,101,47,104,101,97,100,62,60,98,111,100,121,102,108, +111,97,116,58,108,101,102,116,59,60,108,105,32,99,108,97,115,115,61,34,104,117, +110,100,114,101,100,115,32,111,102,10,10,72,111,119,101,118,101,114,44,32,99,111 +,109,112,111,115,105,116,105,111,110,99,108,101,97,114,58,98,111,116,104,59,99, +111,111,112,101,114,97,116,105,111,110,119,105,116,104,105,110,32,116,104,101,32 +,108,97,98,101,108,32,102,111,114,61,34,98,111,114,100,101,114,45,116,111,112,58 +,78,101,119,32,90,101,97,108,97,110,100,114,101,99,111,109,109,101,110,100,101, +100,112,104,111,116,111,103,114,97,112,104,121,105,110,116,101,114,101,115,116, +105,110,103,38,108,116,59,115,117,112,38,103,116,59,99,111,110,116,114,111,118, +101,114,115,121,78,101,116,104,101,114,108,97,110,100,115,97,108,116,101,114,110 +,97,116,105,118,101,109,97,120,108,101,110,103,116,104,61,34,115,119,105,116,122 +,101,114,108,97,110,100,68,101,118,101,108,111,112,109,101,110,116,101,115,115, +101,110,116,105,97,108,108,121,10,10,65,108,116,104,111,117,103,104,32,60,47,116 +,101,120,116,97,114,101,97,62,116,104,117,110,100,101,114,98,105,114,100,114,101 +,112,114,101,115,101,110,116,101,100,38,97,109,112,59,110,100,97,115,104,59,115, +112,101,99,117,108,97,116,105,111,110,99,111,109,109,117,110,105,116,105,101,115 +,108,101,103,105,115,108,97,116,105,111,110,101,108,101,99,116,114,111,110,105, +99,115,10,9,60,100,105,118,32,105,100,61,34,105,108,108,117,115,116,114,97,116, +101,100,101,110,103,105,110,101,101,114,105,110,103,116,101,114,114,105,116,111, +114,105,101,115,97,117,116,104,111,114,105,116,105,101,115,100,105,115,116,114, +105,98,117,116,101,100,54,34,32,104,101,105,103,104,116,61,34,115,97,110,115,45, +115,101,114,105,102,59,99,97,112,97,98,108,101,32,111,102,32,100,105,115,97,112, +112,101,97,114,101,100,105,110,116,101,114,97,99,116,105,118,101,108,111,111,107 +,105,110,103,32,102,111,114,105,116,32,119,111,117,108,100,32,98,101,65,102,103, +104,97,110,105,115,116,97,110,119,97,115,32,99,114,101,97,116,101,100,77,97,116, +104,46,102,108,111,111,114,40,115,117,114,114,111,117,110,100,105,110,103,99,97, +110,32,97,108,115,111,32,98,101,111,98,115,101,114,118,97,116,105,111,110,109,97 +,105,110,116,101,110,97,110,99,101,101,110,99,111,117,110,116,101,114,101,100,60 +,104,50,32,99,108,97,115,115,61,34,109,111,114,101,32,114,101,99,101,110,116,105 +,116,32,104,97,115,32,98,101,101,110,105,110,118,97,115,105,111,110,32,111,102, +41,46,103,101,116,84,105,109,101,40,41,102,117,110,100,97,109,101,110,116,97,108 +,68,101,115,112,105,116,101,32,116,104,101,34,62,60,100,105,118,32,105,100,61,34 +,105,110,115,112,105,114,97,116,105,111,110,101,120,97,109,105,110,97,116,105, +111,110,112,114,101,112,97,114,97,116,105,111,110,101,120,112,108,97,110,97,116, +105,111,110,60,105,110,112,117,116,32,105,100,61,34,60,47,97,62,60,47,115,112,97 +,110,62,118,101,114,115,105,111,110,115,32,111,102,105,110,115,116,114,117,109, +101,110,116,115,98,101,102,111,114,101,32,116,104,101,32,32,61,32,39,104,116,116 +,112,58,47,47,68,101,115,99,114,105,112,116,105,111,110,114,101,108,97,116,105, +118,101,108,121,32,46,115,117,98,115,116,114,105,110,103,40,101,97,99,104,32,111 +,102,32,116,104,101,101,120,112,101,114,105,109,101,110,116,115,105,110,102,108, +117,101,110,116,105,97,108,105,110,116,101,103,114,97,116,105,111,110,109,97,110 +,121,32,112,101,111,112,108,101,100,117,101,32,116,111,32,116,104,101,32,99,111, +109,98,105,110,97,116,105,111,110,100,111,32,110,111,116,32,104,97,118,101,77, +105,100,100,108,101,32,69,97,115,116,60,110,111,115,99,114,105,112,116,62,60,99, +111,112,121,114,105,103,104,116,34,32,112,101,114,104,97,112,115,32,116,104,101, +105,110,115,116,105,116,117,116,105,111,110,105,110,32,68,101,99,101,109,98,101, +114,97,114,114,97,110,103,101,109,101,110,116,109,111,115,116,32,102,97,109,111, +117,115,112,101,114,115,111,110,97,108,105,116,121,99,114,101,97,116,105,111,110 +,32,111,102,108,105,109,105,116,97,116,105,111,110,115,101,120,99,108,117,115, +105,118,101,108,121,115,111,118,101,114,101,105,103,110,116,121,45,99,111,110, +116,101,110,116,34,62,10,60,116,100,32,99,108,97,115,115,61,34,117,110,100,101, +114,103,114,111,117,110,100,112,97,114,97,108,108,101,108,32,116,111,100,111,99, +116,114,105,110,101,32,111,102,111,99,99,117,112,105,101,100,32,98,121,116,101, +114,109,105,110,111,108,111,103,121,82,101,110,97,105,115,115,97,110,99,101,97, +32,110,117,109,98,101,114,32,111,102,115,117,112,112,111,114,116,32,102,111,114, +101,120,112,108,111,114,97,116,105,111,110,114,101,99,111,103,110,105,116,105, +111,110,112,114,101,100,101,99,101,115,115,111,114,60,105,109,103,32,115,114,99, +61,34,47,60,104,49,32,99,108,97,115,115,61,34,112,117,98,108,105,99,97,116,105, +111,110,109,97,121,32,97,108,115,111,32,98,101,115,112,101,99,105,97,108,105,122 +,101,100,60,47,102,105,101,108,100,115,101,116,62,112,114,111,103,114,101,115, +115,105,118,101,109,105,108,108,105,111,110,115,32,111,102,115,116,97,116,101, +115,32,116,104,97,116,101,110,102,111,114,99,101,109,101,110,116,97,114,111,117, +110,100,32,116,104,101,32,111,110,101,32,97,110,111,116,104,101,114,46,112,97, +114,101,110,116,78,111,100,101,97,103,114,105,99,117,108,116,117,114,101,65,108, +116,101,114,110,97,116,105,118,101,114,101,115,101,97,114,99,104,101,114,115,116 +,111,119,97,114,100,115,32,116,104,101,77,111,115,116,32,111,102,32,116,104,101, +109,97,110,121,32,111,116,104,101,114,32,40,101,115,112,101,99,105,97,108,108, +121,60,116,100,32,119,105,100,116,104,61,34,59,119,105,100,116,104,58,49,48,48, +37,105,110,100,101,112,101,110,100,101,110,116,60,104,51,32,99,108,97,115,115,61 +,34,32,111,110,99,104,97,110,103,101,61,34,41,46,97,100,100,67,108,97,115,115,40 +,105,110,116,101,114,97,99,116,105,111,110,79,110,101,32,111,102,32,116,104,101, +32,100,97,117,103,104,116,101,114,32,111,102,97,99,99,101,115,115,111,114,105, +101,115,98,114,97,110,99,104,101,115,32,111,102,13,10,60,100,105,118,32,105,100, +61,34,116,104,101,32,108,97,114,103,101,115,116,100,101,99,108,97,114,97,116,105 +,111,110,114,101,103,117,108,97,116,105,111,110,115,73,110,102,111,114,109,97, +116,105,111,110,116,114,97,110,115,108,97,116,105,111,110,100,111,99,117,109,101 +,110,116,97,114,121,105,110,32,111,114,100,101,114,32,116,111,34,62,10,60,104, +101,97,100,62,10,60,34,32,104,101,105,103,104,116,61,34,49,97,99,114,111,115,115 +,32,116,104,101,32,111,114,105,101,110,116,97,116,105,111,110,41,59,60,47,115,99 +,114,105,112,116,62,105,109,112,108,101,109,101,110,116,101,100,99,97,110,32,98, +101,32,115,101,101,110,116,104,101,114,101,32,119,97,115,32,97,100,101,109,111, +110,115,116,114,97,116,101,99,111,110,116,97,105,110,101,114,34,62,99,111,110, +110,101,99,116,105,111,110,115,116,104,101,32,66,114,105,116,105,115,104,119,97, +115,32,119,114,105,116,116,101,110,33,105,109,112,111,114,116,97,110,116,59,112, +120,59,32,109,97,114,103,105,110,45,102,111,108,108,111,119,101,100,32,98,121,97 +,98,105,108,105,116,121,32,116,111,32,99,111,109,112,108,105,99,97,116,101,100, +100,117,114,105,110,103,32,116,104,101,32,105,109,109,105,103,114,97,116,105,111 +,110,97,108,115,111,32,99,97,108,108,101,100,60,104,52,32,99,108,97,115,115,61, +34,100,105,115,116,105,110,99,116,105,111,110,114,101,112,108,97,99,101,100,32, +98,121,103,111,118,101,114,110,109,101,110,116,115,108,111,99,97,116,105,111,110 +,32,111,102,105,110,32,78,111,118,101,109,98,101,114,119,104,101,116,104,101,114 +,32,116,104,101,60,47,112,62,10,60,47,100,105,118,62,97,99,113,117,105,115,105, +116,105,111,110,99,97,108,108,101,100,32,116,104,101,32,112,101,114,115,101,99, +117,116,105,111,110,100,101,115,105,103,110,97,116,105,111,110,123,102,111,110, +116,45,115,105,122,101,58,97,112,112,101,97,114,101,100,32,105,110,105,110,118, +101,115,116,105,103,97,116,101,101,120,112,101,114,105,101,110,99,101,100,109, +111,115,116,32,108,105,107,101,108,121,119,105,100,101,108,121,32,117,115,101, +100,100,105,115,99,117,115,115,105,111,110,115,112,114,101,115,101,110,99,101,32 +,111,102,32,40,100,111,99,117,109,101,110,116,46,101,120,116,101,110,115,105,118 +,101,108,121,73,116,32,104,97,115,32,98,101,101,110,105,116,32,100,111,101,115, +32,110,111,116,99,111,110,116,114,97,114,121,32,116,111,105,110,104,97,98,105, +116,97,110,116,115,105,109,112,114,111,118,101,109,101,110,116,115,99,104,111, +108,97,114,115,104,105,112,99,111,110,115,117,109,112,116,105,111,110,105,110, +115,116,114,117,99,116,105,111,110,102,111,114,32,101,120,97,109,112,108,101,111 +,110,101,32,111,114,32,109,111,114,101,112,120,59,32,112,97,100,100,105,110,103, +116,104,101,32,99,117,114,114,101,110,116,97,32,115,101,114,105,101,115,32,111, +102,97,114,101,32,117,115,117,97,108,108,121,114,111,108,101,32,105,110,32,116, +104,101,112,114,101,118,105,111,117,115,108,121,32,100,101,114,105,118,97,116, +105,118,101,115,101,118,105,100,101,110,99,101,32,111,102,101,120,112,101,114, +105,101,110,99,101,115,99,111,108,111,114,115,99,104,101,109,101,115,116,97,116, +101,100,32,116,104,97,116,99,101,114,116,105,102,105,99,97,116,101,60,47,97,62, +60,47,100,105,118,62,10,32,115,101,108,101,99,116,101,100,61,34,104,105,103,104, +32,115,99,104,111,111,108,114,101,115,112,111,110,115,101,32,116,111,99,111,109, +102,111,114,116,97,98,108,101,97,100,111,112,116,105,111,110,32,111,102,116,104, +114,101,101,32,121,101,97,114,115,116,104,101,32,99,111,117,110,116,114,121,105, +110,32,70,101,98,114,117,97,114,121,115,111,32,116,104,97,116,32,116,104,101,112 +,101,111,112,108,101,32,119,104,111,32,112,114,111,118,105,100,101,100,32,98,121 +,60,112,97,114,97,109,32,110,97,109,101,97,102,102,101,99,116,101,100,32,98,121, +105,110,32,116,101,114,109,115,32,111,102,97,112,112,111,105,110,116,109,101,110 +,116,73,83,79,45,56,56,53,57,45,49,34,119,97,115,32,98,111,114,110,32,105,110, +104,105,115,116,111,114,105,99,97,108,32,114,101,103,97,114,100,101,100,32,97, +115,109,101,97,115,117,114,101,109,101,110,116,105,115,32,98,97,115,101,100,32, +111,110,32,97,110,100,32,111,116,104,101,114,32,58,32,102,117,110,99,116,105,111 +,110,40,115,105,103,110,105,102,105,99,97,110,116,99,101,108,101,98,114,97,116, +105,111,110,116,114,97,110,115,109,105,116,116,101,100,47,106,115,47,106,113,117 +,101,114,121,46,105,115,32,107,110,111,119,110,32,97,115,116,104,101,111,114,101 +,116,105,99,97,108,32,116,97,98,105,110,100,101,120,61,34,105,116,32,99,111,117, +108,100,32,98,101,60,110,111,115,99,114,105,112,116,62,10,104,97,118,105,110,103 +,32,98,101,101,110,13,10,60,104,101,97,100,62,13,10,60,32,38,113,117,111,116,59, +84,104,101,32,99,111,109,112,105,108,97,116,105,111,110,104,101,32,104,97,100,32 +,98,101,101,110,112,114,111,100,117,99,101,100,32,98,121,112,104,105,108,111,115 +,111,112,104,101,114,99,111,110,115,116,114,117,99,116,101,100,105,110,116,101, +110,100,101,100,32,116,111,97,109,111,110,103,32,111,116,104,101,114,99,111,109, +112,97,114,101,100,32,116,111,116,111,32,115,97,121,32,116,104,97,116,69,110,103 +,105,110,101,101,114,105,110,103,97,32,100,105,102,102,101,114,101,110,116,114, +101,102,101,114,114,101,100,32,116,111,100,105,102,102,101,114,101,110,99,101, +115,98,101,108,105,101,102,32,116,104,97,116,112,104,111,116,111,103,114,97,112, +104,115,105,100,101,110,116,105,102,121,105,110,103,72,105,115,116,111,114,121, +32,111,102,32,82,101,112,117,98,108,105,99,32,111,102,110,101,99,101,115,115,97, +114,105,108,121,112,114,111,98,97,98,105,108,105,116,121,116,101,99,104,110,105, +99,97,108,108,121,108,101,97,118,105,110,103,32,116,104,101,115,112,101,99,116, +97,99,117,108,97,114,102,114,97,99,116,105,111,110,32,111,102,101,108,101,99,116 +,114,105,99,105,116,121,104,101,97,100,32,111,102,32,116,104,101,114,101,115,116 +,97,117,114,97,110,116,115,112,97,114,116,110,101,114,115,104,105,112,101,109, +112,104,97,115,105,115,32,111,110,109,111,115,116,32,114,101,99,101,110,116,115, +104,97,114,101,32,119,105,116,104,32,115,97,121,105,110,103,32,116,104,97,116, +102,105,108,108,101,100,32,119,105,116,104,100,101,115,105,103,110,101,100,32, +116,111,105,116,32,105,115,32,111,102,116,101,110,34,62,60,47,105,102,114,97,109 +,101,62,97,115,32,102,111,108,108,111,119,115,58,109,101,114,103,101,100,32,119, +105,116,104,116,104,114,111,117,103,104,32,116,104,101,99,111,109,109,101,114,99 +,105,97,108,32,112,111,105,110,116,101,100,32,111,117,116,111,112,112,111,114, +116,117,110,105,116,121,118,105,101,119,32,111,102,32,116,104,101,114,101,113, +117,105,114,101,109,101,110,116,100,105,118,105,115,105,111,110,32,111,102,112, +114,111,103,114,97,109,109,105,110,103,104,101,32,114,101,99,101,105,118,101,100 +,115,101,116,73,110,116,101,114,118,97,108,34,62,60,47,115,112,97,110,62,60,47, +105,110,32,78,101,119,32,89,111,114,107,97,100,100,105,116,105,111,110,97,108,32 +,99,111,109,112,114,101,115,115,105,111,110,10,10,60,100,105,118,32,105,100,61, +34,105,110,99,111,114,112,111,114,97,116,101,59,60,47,115,99,114,105,112,116,62, +60,97,116,116,97,99,104,69,118,101,110,116,98,101,99,97,109,101,32,116,104,101, +32,34,32,116,97,114,103,101,116,61,34,95,99,97,114,114,105,101,100,32,111,117, +116,83,111,109,101,32,111,102,32,116,104,101,115,99,105,101,110,99,101,32,97,110 +,100,116,104,101,32,116,105,109,101,32,111,102,67,111,110,116,97,105,110,101,114 +,34,62,109,97,105,110,116,97,105,110,105,110,103,67,104,114,105,115,116,111,112, +104,101,114,77,117,99,104,32,111,102,32,116,104,101,119,114,105,116,105,110,103, +115,32,111,102,34,32,104,101,105,103,104,116,61,34,50,115,105,122,101,32,111,102 +,32,116,104,101,118,101,114,115,105,111,110,32,111,102,32,109,105,120,116,117, +114,101,32,111,102,32,98,101,116,119,101,101,110,32,116,104,101,69,120,97,109, +112,108,101,115,32,111,102,101,100,117,99,97,116,105,111,110,97,108,99,111,109, +112,101,116,105,116,105,118,101,32,111,110,115,117,98,109,105,116,61,34,100,105, +114,101,99,116,111,114,32,111,102,100,105,115,116,105,110,99,116,105,118,101,47, +68,84,68,32,88,72,84,77,76,32,114,101,108,97,116,105,110,103,32,116,111,116,101, +110,100,101,110,99,121,32,116,111,112,114,111,118,105,110,99,101,32,111,102,119, +104,105,99,104,32,119,111,117,108,100,100,101,115,112,105,116,101,32,116,104,101 +,115,99,105,101,110,116,105,102,105,99,32,108,101,103,105,115,108,97,116,117,114 +,101,46,105,110,110,101,114,72,84,77,76,32,97,108,108,101,103,97,116,105,111,110 +,115,65,103,114,105,99,117,108,116,117,114,101,119,97,115,32,117,115,101,100,32, +105,110,97,112,112,114,111,97,99,104,32,116,111,105,110,116,101,108,108,105,103, +101,110,116,121,101,97,114,115,32,108,97,116,101,114,44,115,97,110,115,45,115, +101,114,105,102,100,101,116,101,114,109,105,110,105,110,103,80,101,114,102,111, +114,109,97,110,99,101,97,112,112,101,97,114,97,110,99,101,115,44,32,119,104,105, +99,104,32,105,115,32,102,111,117,110,100,97,116,105,111,110,115,97,98,98,114,101 +,118,105,97,116,101,100,104,105,103,104,101,114,32,116,104,97,110,115,32,102,114 +,111,109,32,116,104,101,32,105,110,100,105,118,105,100,117,97,108,32,99,111,109, +112,111,115,101,100,32,111,102,115,117,112,112,111,115,101,100,32,116,111,99,108 +,97,105,109,115,32,116,104,97,116,97,116,116,114,105,98,117,116,105,111,110,102, +111,110,116,45,115,105,122,101,58,49,101,108,101,109,101,110,116,115,32,111,102, +72,105,115,116,111,114,105,99,97,108,32,104,105,115,32,98,114,111,116,104,101, +114,97,116,32,116,104,101,32,116,105,109,101,97,110,110,105,118,101,114,115,97, +114,121,103,111,118,101,114,110,101,100,32,98,121,114,101,108,97,116,101,100,32, +116,111,32,117,108,116,105,109,97,116,101,108,121,32,105,110,110,111,118,97,116, +105,111,110,115,105,116,32,105,115,32,115,116,105,108,108,99,97,110,32,111,110, +108,121,32,98,101,100,101,102,105,110,105,116,105,111,110,115,116,111,71,77,84, +83,116,114,105,110,103,65,32,110,117,109,98,101,114,32,111,102,105,109,103,32,99 +,108,97,115,115,61,34,69,118,101,110,116,117,97,108,108,121,44,119,97,115,32,99, +104,97,110,103,101,100,111,99,99,117,114,114,101,100,32,105,110,110,101,105,103, +104,98,111,114,105,110,103,100,105,115,116,105,110,103,117,105,115,104,119,104, +101,110,32,104,101,32,119,97,115,105,110,116,114,111,100,117,99,105,110,103,116, +101,114,114,101,115,116,114,105,97,108,77,97,110,121,32,111,102,32,116,104,101, +97,114,103,117,101,115,32,116,104,97,116,97,110,32,65,109,101,114,105,99,97,110, +99,111,110,113,117,101,115,116,32,111,102,119,105,100,101,115,112,114,101,97,100 +,32,119,101,114,101,32,107,105,108,108,101,100,115,99,114,101,101,110,32,97,110, +100,32,73,110,32,111,114,100,101,114,32,116,111,101,120,112,101,99,116,101,100, +32,116,111,100,101,115,99,101,110,100,97,110,116,115,97,114,101,32,108,111,99,97 +,116,101,100,108,101,103,105,115,108,97,116,105,118,101,103,101,110,101,114,97, +116,105,111,110,115,32,98,97,99,107,103,114,111,117,110,100,109,111,115,116,32, +112,101,111,112,108,101,121,101,97,114,115,32,97,102,116,101,114,116,104,101,114 +,101,32,105,115,32,110,111,116,104,101,32,104,105,103,104,101,115,116,102,114, +101,113,117,101,110,116,108,121,32,116,104,101,121,32,100,111,32,110,111,116,97, +114,103,117,101,100,32,116,104,97,116,115,104,111,119,101,100,32,116,104,97,116, +112,114,101,100,111,109,105,110,97,110,116,116,104,101,111,108,111,103,105,99,97 +,108,98,121,32,116,104,101,32,116,105,109,101,99,111,110,115,105,100,101,114,105 +,110,103,115,104,111,114,116,45,108,105,118,101,100,60,47,115,112,97,110,62,60, +47,97,62,99,97,110,32,98,101,32,117,115,101,100,118,101,114,121,32,108,105,116, +116,108,101,111,110,101,32,111,102,32,116,104,101,32,104,97,100,32,97,108,114, +101,97,100,121,105,110,116,101,114,112,114,101,116,101,100,99,111,109,109,117, +110,105,99,97,116,101,102,101,97,116,117,114,101,115,32,111,102,103,111,118,101, +114,110,109,101,110,116,44,60,47,110,111,115,99,114,105,112,116,62,101,110,116, +101,114,101,100,32,116,104,101,34,32,104,101,105,103,104,116,61,34,51,73,110,100 +,101,112,101,110,100,101,110,116,112,111,112,117,108,97,116,105,111,110,115,108, +97,114,103,101,45,115,99,97,108,101,46,32,65,108,116,104,111,117,103,104,32,117, +115,101,100,32,105,110,32,116,104,101,100,101,115,116,114,117,99,116,105,111,110 +,112,111,115,115,105,98,105,108,105,116,121,115,116,97,114,116,105,110,103,32, +105,110,116,119,111,32,111,114,32,109,111,114,101,101,120,112,114,101,115,115, +105,111,110,115,115,117,98,111,114,100,105,110,97,116,101,108,97,114,103,101,114 +,32,116,104,97,110,104,105,115,116,111,114,121,32,97,110,100,60,47,111,112,116, +105,111,110,62,13,10,67,111,110,116,105,110,101,110,116,97,108,101,108,105,109, +105,110,97,116,105,110,103,119,105,108,108,32,110,111,116,32,98,101,112,114,97, +99,116,105,99,101,32,111,102,105,110,32,102,114,111,110,116,32,111,102,115,105, +116,101,32,111,102,32,116,104,101,101,110,115,117,114,101,32,116,104,97,116,116, +111,32,99,114,101,97,116,101,32,97,109,105,115,115,105,115,115,105,112,112,105, +112,111,116,101,110,116,105,97,108,108,121,111,117,116,115,116,97,110,100,105, +110,103,98,101,116,116,101,114,32,116,104,97,110,119,104,97,116,32,105,115,32, +110,111,119,115,105,116,117,97,116,101,100,32,105,110,109,101,116,97,32,110,97, +109,101,61,34,84,114,97,100,105,116,105,111,110,97,108,115,117,103,103,101,115, +116,105,111,110,115,84,114,97,110,115,108,97,116,105,111,110,116,104,101,32,102, +111,114,109,32,111,102,97,116,109,111,115,112,104,101,114,105,99,105,100,101,111 +,108,111,103,105,99,97,108,101,110,116,101,114,112,114,105,115,101,115,99,97,108 +,99,117,108,97,116,105,110,103,101,97,115,116,32,111,102,32,116,104,101,114,101, +109,110,97,110,116,115,32,111,102,112,108,117,103,105,110,115,112,97,103,101,47, +105,110,100,101,120,46,112,104,112,63,114,101,109,97,105,110,101,100,32,105,110, +116,114,97,110,115,102,111,114,109,101,100,72,101,32,119,97,115,32,97,108,115, +111,119,97,115,32,97,108,114,101,97,100,121,115,116,97,116,105,115,116,105,99,97 +,108,105,110,32,102,97,118,111,114,32,111,102,77,105,110,105,115,116,114,121,32, +111,102,109,111,118,101,109,101,110,116,32,111,102,102,111,114,109,117,108,97, +116,105,111,110,105,115,32,114,101,113,117,105,114,101,100,60,108,105,110,107,32 +,114,101,108,61,34,84,104,105,115,32,105,115,32,116,104,101,32,60,97,32,104,114, +101,102,61,34,47,112,111,112,117,108,97,114,105,122,101,100,105,110,118,111,108, +118,101,100,32,105,110,97,114,101,32,117,115,101,100,32,116,111,97,110,100,32, +115,101,118,101,114,97,108,109,97,100,101,32,98,121,32,116,104,101,115,101,101, +109,115,32,116,111,32,98,101,108,105,107,101,108,121,32,116,104,97,116,80,97,108 +,101,115,116,105,110,105,97,110,110,97,109,101,100,32,97,102,116,101,114,105,116 +,32,104,97,100,32,98,101,101,110,109,111,115,116,32,99,111,109,109,111,110,116, +111,32,114,101,102,101,114,32,116,111,98,117,116,32,116,104,105,115,32,105,115, +99,111,110,115,101,99,117,116,105,118,101,116,101,109,112,111,114,97,114,105,108 +,121,73,110,32,103,101,110,101,114,97,108,44,99,111,110,118,101,110,116,105,111, +110,115,116,97,107,101,115,32,112,108,97,99,101,115,117,98,100,105,118,105,115, +105,111,110,116,101,114,114,105,116,111,114,105,97,108,111,112,101,114,97,116, +105,111,110,97,108,112,101,114,109,97,110,101,110,116,108,121,119,97,115,32,108, +97,114,103,101,108,121,111,117,116,98,114,101,97,107,32,111,102,105,110,32,116, +104,101,32,112,97,115,116,102,111,108,108,111,119,105,110,103,32,97,32,120,109, +108,110,115,58,111,103,61,34,62,60,97,32,99,108,97,115,115,61,34,99,108,97,115, +115,61,34,116,101,120,116,67,111,110,118,101,114,115,105,111,110,32,109,97,121, +32,98,101,32,117,115,101,100,109,97,110,117,102,97,99,116,117,114,101,97,102,116 +,101,114,32,98,101,105,110,103,99,108,101,97,114,102,105,120,34,62,10,113,117, +101,115,116,105,111,110,32,111,102,119,97,115,32,101,108,101,99,116,101,100,116, +111,32,98,101,99,111,109,101,32,97,98,101,99,97,117,115,101,32,111,102,32,115, +111,109,101,32,112,101,111,112,108,101,105,110,115,112,105,114,101,100,32,98,121 +,115,117,99,99,101,115,115,102,117,108,32,97,32,116,105,109,101,32,119,104,101, +110,109,111,114,101,32,99,111,109,109,111,110,97,109,111,110,103,115,116,32,116, +104,101,97,110,32,111,102,102,105,99,105,97,108,119,105,100,116,104,58,49,48,48, +37,59,116,101,99,104,110,111,108,111,103,121,44,119,97,115,32,97,100,111,112,116 +,101,100,116,111,32,107,101,101,112,32,116,104,101,115,101,116,116,108,101,109, +101,110,116,115,108,105,118,101,32,98,105,114,116,104,115,105,110,100,101,120,46 +,104,116,109,108,34,67,111,110,110,101,99,116,105,99,117,116,97,115,115,105,103, +110,101,100,32,116,111,38,97,109,112,59,116,105,109,101,115,59,97,99,99,111,117, +110,116,32,102,111,114,97,108,105,103,110,61,114,105,103,104,116,116,104,101,32, +99,111,109,112,97,110,121,97,108,119,97,121,115,32,98,101,101,110,114,101,116, +117,114,110,101,100,32,116,111,105,110,118,111,108,118,101,109,101,110,116,66, +101,99,97,117,115,101,32,116,104,101,116,104,105,115,32,112,101,114,105,111,100, +34,32,110,97,109,101,61,34,113,34,32,99,111,110,102,105,110,101,100,32,116,111, +97,32,114,101,115,117,108,116,32,111,102,118,97,108,117,101,61,34,34,32,47,62, +105,115,32,97,99,116,117,97,108,108,121,69,110,118,105,114,111,110,109,101,110, +116,13,10,60,47,104,101,97,100,62,13,10,67,111,110,118,101,114,115,101,108,121, +44,62,10,60,100,105,118,32,105,100,61,34,48,34,32,119,105,100,116,104,61,34,49, +105,115,32,112,114,111,98,97,98,108,121,104,97,118,101,32,98,101,99,111,109,101, +99,111,110,116,114,111,108,108,105,110,103,116,104,101,32,112,114,111,98,108,101 +,109,99,105,116,105,122,101,110,115,32,111,102,112,111,108,105,116,105,99,105,97 +,110,115,114,101,97,99,104,101,100,32,116,104,101,97,115,32,101,97,114,108,121, +32,97,115,58,110,111,110,101,59,32,111,118,101,114,60,116,97,98,108,101,32,99, +101,108,108,118,97,108,105,100,105,116,121,32,111,102,100,105,114,101,99,116,108 +,121,32,116,111,111,110,109,111,117,115,101,100,111,119,110,119,104,101,114,101, +32,105,116,32,105,115,119,104,101,110,32,105,116,32,119,97,115,109,101,109,98, +101,114,115,32,111,102,32,114,101,108,97,116,105,111,110,32,116,111,97,99,99,111 +,109,109,111,100,97,116,101,97,108,111,110,103,32,119,105,116,104,32,73,110,32, +116,104,101,32,108,97,116,101,116,104,101,32,69,110,103,108,105,115,104,100,101, +108,105,99,105,111,117,115,34,62,116,104,105,115,32,105,115,32,110,111,116,116, +104,101,32,112,114,101,115,101,110,116,105,102,32,116,104,101,121,32,97,114,101, +97,110,100,32,102,105,110,97,108,108,121,97,32,109,97,116,116,101,114,32,111,102 +,13,10,9,60,47,100,105,118,62,13,10,13,10,60,47,115,99,114,105,112,116,62,102,97 +,115,116,101,114,32,116,104,97,110,109,97,106,111,114,105,116,121,32,111,102,97, +102,116,101,114,32,119,104,105,99,104,99,111,109,112,97,114,97,116,105,118,101, +116,111,32,109,97,105,110,116,97,105,110,105,109,112,114,111,118,101,32,116,104, +101,97,119,97,114,100,101,100,32,116,104,101,101,114,34,32,99,108,97,115,115,61, +34,102,114,97,109,101,98,111,114,100,101,114,114,101,115,116,111,114,97,116,105, +111,110,105,110,32,116,104,101,32,115,97,109,101,97,110,97,108,121,115,105,115, +32,111,102,116,104,101,105,114,32,102,105,114,115,116,68,117,114,105,110,103,32, +116,104,101,32,99,111,110,116,105,110,101,110,116,97,108,115,101,113,117,101,110 +,99,101,32,111,102,102,117,110,99,116,105,111,110,40,41,123,102,111,110,116,45, +115,105,122,101,58,32,119,111,114,107,32,111,110,32,116,104,101,60,47,115,99,114 +,105,112,116,62,10,60,98,101,103,105,110,115,32,119,105,116,104,106,97,118,97, +115,99,114,105,112,116,58,99,111,110,115,116,105,116,117,101,110,116,119,97,115, +32,102,111,117,110,100,101,100,101,113,117,105,108,105,98,114,105,117,109,97,115 +,115,117,109,101,32,116,104,97,116,105,115,32,103,105,118,101,110,32,98,121,110, +101,101,100,115,32,116,111,32,98,101,99,111,111,114,100,105,110,97,116,101,115, +116,104,101,32,118,97,114,105,111,117,115,97,114,101,32,112,97,114,116,32,111, +102,111,110,108,121,32,105,110,32,116,104,101,115,101,99,116,105,111,110,115,32, +111,102,105,115,32,97,32,99,111,109,109,111,110,116,104,101,111,114,105,101,115, +32,111,102,100,105,115,99,111,118,101,114,105,101,115,97,115,115,111,99,105,97, +116,105,111,110,101,100,103,101,32,111,102,32,116,104,101,115,116,114,101,110, +103,116,104,32,111,102,112,111,115,105,116,105,111,110,32,105,110,112,114,101, +115,101,110,116,45,100,97,121,117,110,105,118,101,114,115,97,108,108,121,116,111 +,32,102,111,114,109,32,116,104,101,98,117,116,32,105,110,115,116,101,97,100,99, +111,114,112,111,114,97,116,105,111,110,97,116,116,97,99,104,101,100,32,116,111, +105,115,32,99,111,109,109,111,110,108,121,114,101,97,115,111,110,115,32,102,111, +114,32,38,113,117,111,116,59,116,104,101,32,99,97,110,32,98,101,32,109,97,100, +101,119,97,115,32,97,98,108,101,32,116,111,119,104,105,99,104,32,109,101,97,110, +115,98,117,116,32,100,105,100,32,110,111,116,111,110,77,111,117,115,101,79,118, +101,114,97,115,32,112,111,115,115,105,98,108,101,111,112,101,114,97,116,101,100, +32,98,121,99,111,109,105,110,103,32,102,114,111,109,116,104,101,32,112,114,105, +109,97,114,121,97,100,100,105,116,105,111,110,32,111,102,102,111,114,32,115,101, +118,101,114,97,108,116,114,97,110,115,102,101,114,114,101,100,97,32,112,101,114, +105,111,100,32,111,102,97,114,101,32,97,98,108,101,32,116,111,104,111,119,101, +118,101,114,44,32,105,116,115,104,111,117,108,100,32,104,97,118,101,109,117,99, +104,32,108,97,114,103,101,114,10,9,60,47,115,99,114,105,112,116,62,97,100,111, +112,116,101,100,32,116,104,101,112,114,111,112,101,114,116,121,32,111,102,100, +105,114,101,99,116,101,100,32,98,121,101,102,102,101,99,116,105,118,101,108,121, +119,97,115,32,98,114,111,117,103,104,116,99,104,105,108,100,114,101,110,32,111, +102,80,114,111,103,114,97,109,109,105,110,103,108,111,110,103,101,114,32,116,104 +,97,110,109,97,110,117,115,99,114,105,112,116,115,119,97,114,32,97,103,97,105, +110,115,116,98,121,32,109,101,97,110,115,32,111,102,97,110,100,32,109,111,115, +116,32,111,102,115,105,109,105,108,97,114,32,116,111,32,112,114,111,112,114,105, +101,116,97,114,121,111,114,105,103,105,110,97,116,105,110,103,112,114,101,115, +116,105,103,105,111,117,115,103,114,97,109,109,97,116,105,99,97,108,101,120,112, +101,114,105,101,110,99,101,46,116,111,32,109,97,107,101,32,116,104,101,73,116,32 +,119,97,115,32,97,108,115,111,105,115,32,102,111,117,110,100,32,105,110,99,111, +109,112,101,116,105,116,111,114,115,105,110,32,116,104,101,32,85,46,83,46,114, +101,112,108,97,99,101,32,116,104,101,98,114,111,117,103,104,116,32,116,104,101, +99,97,108,99,117,108,97,116,105,111,110,102,97,108,108,32,111,102,32,116,104,101 +,116,104,101,32,103,101,110,101,114,97,108,112,114,97,99,116,105,99,97,108,108, +121,105,110,32,104,111,110,111,114,32,111,102,114,101,108,101,97,115,101,100,32, +105,110,114,101,115,105,100,101,110,116,105,97,108,97,110,100,32,115,111,109,101 +,32,111,102,107,105,110,103,32,111,102,32,116,104,101,114,101,97,99,116,105,111, +110,32,116,111,49,115,116,32,69,97,114,108,32,111,102,99,117,108,116,117,114,101 +,32,97,110,100,112,114,105,110,99,105,112,97,108,108,121,60,47,116,105,116,108, +101,62,10,32,32,116,104,101,121,32,99,97,110,32,98,101,98,97,99,107,32,116,111, +32,116,104,101,115,111,109,101,32,111,102,32,104,105,115,101,120,112,111,115,117 +,114,101,32,116,111,97,114,101,32,115,105,109,105,108,97,114,102,111,114,109,32, +111,102,32,116,104,101,97,100,100,70,97,118,111,114,105,116,101,99,105,116,105, +122,101,110,115,104,105,112,112,97,114,116,32,105,110,32,116,104,101,112,101,111 +,112,108,101,32,119,105,116,104,105,110,32,112,114,97,99,116,105,99,101,116,111, +32,99,111,110,116,105,110,117,101,38,97,109,112,59,109,105,110,117,115,59,97,112 +,112,114,111,118,101,100,32,98,121,32,116,104,101,32,102,105,114,115,116,32,97, +108,108,111,119,101,100,32,116,104,101,97,110,100,32,102,111,114,32,116,104,101, +102,117,110,99,116,105,111,110,105,110,103,112,108,97,121,105,110,103,32,116,104 +,101,115,111,108,117,116,105,111,110,32,116,111,104,101,105,103,104,116,61,34,48 +,34,32,105,110,32,104,105,115,32,98,111,111,107,109,111,114,101,32,116,104,97, +110,32,97,102,111,108,108,111,119,115,32,116,104,101,99,114,101,97,116,101,100, +32,116,104,101,112,114,101,115,101,110,99,101,32,105,110,38,110,98,115,112,59,60 +,47,116,100,62,110,97,116,105,111,110,97,108,105,115,116,116,104,101,32,105,100, +101,97,32,111,102,97,32,99,104,97,114,97,99,116,101,114,119,101,114,101,32,102, +111,114,99,101,100,32,99,108,97,115,115,61,34,98,116,110,100,97,121,115,32,111, +102,32,116,104,101,102,101,97,116,117,114,101,100,32,105,110,115,104,111,119,105 +,110,103,32,116,104,101,105,110,116,101,114,101,115,116,32,105,110,105,110,32, +112,108,97,99,101,32,111,102,116,117,114,110,32,111,102,32,116,104,101,116,104, +101,32,104,101,97,100,32,111,102,76,111,114,100,32,111,102,32,116,104,101,112, +111,108,105,116,105,99,97,108,108,121,104,97,115,32,105,116,115,32,111,119,110, +69,100,117,99,97,116,105,111,110,97,108,97,112,112,114,111,118,97,108,32,111,102 +,115,111,109,101,32,111,102,32,116,104,101,101,97,99,104,32,111,116,104,101,114, +44,98,101,104,97,118,105,111,114,32,111,102,97,110,100,32,98,101,99,97,117,115, +101,97,110,100,32,97,110,111,116,104,101,114,97,112,112,101,97,114,101,100,32, +111,110,114,101,99,111,114,100,101,100,32,105,110,98,108,97,99,107,38,113,117, +111,116,59,109,97,121,32,105,110,99,108,117,100,101,116,104,101,32,119,111,114, +108,100,39,115,99,97,110,32,108,101,97,100,32,116,111,114,101,102,101,114,115,32 +,116,111,32,97,98,111,114,100,101,114,61,34,48,34,32,103,111,118,101,114,110,109 +,101,110,116,32,119,105,110,110,105,110,103,32,116,104,101,114,101,115,117,108, +116,101,100,32,105,110,32,119,104,105,108,101,32,116,104,101,32,87,97,115,104, +105,110,103,116,111,110,44,116,104,101,32,115,117,98,106,101,99,116,99,105,116, +121,32,105,110,32,116,104,101,62,60,47,100,105,118,62,13,10,9,9,114,101,102,108, +101,99,116,32,116,104,101,116,111,32,99,111,109,112,108,101,116,101,98,101,99,97 +,109,101,32,109,111,114,101,114,97,100,105,111,97,99,116,105,118,101,114,101,106 +,101,99,116,101,100,32,98,121,119,105,116,104,111,117,116,32,97,110,121,104,105, +115,32,102,97,116,104,101,114,44,119,104,105,99,104,32,99,111,117,108,100,99,111 +,112,121,32,111,102,32,116,104,101,116,111,32,105,110,100,105,99,97,116,101,97, +32,112,111,108,105,116,105,99,97,108,97,99,99,111,117,110,116,115,32,111,102,99, +111,110,115,116,105,116,117,116,101,115,119,111,114,107,101,100,32,119,105,116, +104,101,114,60,47,97,62,60,47,108,105,62,111,102,32,104,105,115,32,108,105,102, +101,97,99,99,111,109,112,97,110,105,101,100,99,108,105,101,110,116,87,105,100, +116,104,112,114,101,118,101,110,116,32,116,104,101,76,101,103,105,115,108,97,116 +,105,118,101,100,105,102,102,101,114,101,110,116,108,121,116,111,103,101,116,104 +,101,114,32,105,110,104,97,115,32,115,101,118,101,114,97,108,102,111,114,32,97, +110,111,116,104,101,114,116,101,120,116,32,111,102,32,116,104,101,102,111,117, +110,100,101,100,32,116,104,101,101,32,119,105,116,104,32,116,104,101,32,105,115, +32,117,115,101,100,32,102,111,114,99,104,97,110,103,101,100,32,116,104,101,117, +115,117,97,108,108,121,32,116,104,101,112,108,97,99,101,32,119,104,101,114,101, +119,104,101,114,101,97,115,32,116,104,101,62,32,60,97,32,104,114,101,102,61,34, +34,62,60,97,32,104,114,101,102,61,34,116,104,101,109,115,101,108,118,101,115,44, +97,108,116,104,111,117,103,104,32,104,101,116,104,97,116,32,99,97,110,32,98,101, +116,114,97,100,105,116,105,111,110,97,108,114,111,108,101,32,111,102,32,116,104, +101,97,115,32,97,32,114,101,115,117,108,116,114,101,109,111,118,101,67,104,105, +108,100,100,101,115,105,103,110,101,100,32,98,121,119,101,115,116,32,111,102,32, +116,104,101,83,111,109,101,32,112,101,111,112,108,101,112,114,111,100,117,99,116 +,105,111,110,44,115,105,100,101,32,111,102,32,116,104,101,110,101,119,115,108, +101,116,116,101,114,115,117,115,101,100,32,98,121,32,116,104,101,100,111,119,110 +,32,116,111,32,116,104,101,97,99,99,101,112,116,101,100,32,98,121,108,105,118, +101,32,105,110,32,116,104,101,97,116,116,101,109,112,116,115,32,116,111,111,117, +116,115,105,100,101,32,116,104,101,102,114,101,113,117,101,110,99,105,101,115,72 +,111,119,101,118,101,114,44,32,105,110,112,114,111,103,114,97,109,109,101,114, +115,97,116,32,108,101,97,115,116,32,105,110,97,112,112,114,111,120,105,109,97, +116,101,97,108,116,104,111,117,103,104,32,105,116,119,97,115,32,112,97,114,116, +32,111,102,97,110,100,32,118,97,114,105,111,117,115,71,111,118,101,114,110,111, +114,32,111,102,116,104,101,32,97,114,116,105,99,108,101,116,117,114,110,101,100, +32,105,110,116,111,62,60,97,32,104,114,101,102,61,34,47,116,104,101,32,101,99, +111,110,111,109,121,105,115,32,116,104,101,32,109,111,115,116,109,111,115,116,32 +,119,105,100,101,108,121,119,111,117,108,100,32,108,97,116,101,114,97,110,100,32 +,112,101,114,104,97,112,115,114,105,115,101,32,116,111,32,116,104,101,111,99,99, +117,114,115,32,119,104,101,110,117,110,100,101,114,32,119,104,105,99,104,99,111, +110,100,105,116,105,111,110,115,46,116,104,101,32,119,101,115,116,101,114,110, +116,104,101,111,114,121,32,116,104,97,116,105,115,32,112,114,111,100,117,99,101, +100,116,104,101,32,99,105,116,121,32,111,102,105,110,32,119,104,105,99,104,32, +104,101,115,101,101,110,32,105,110,32,116,104,101,116,104,101,32,99,101,110,116, +114,97,108,98,117,105,108,100,105,110,103,32,111,102,109,97,110,121,32,111,102, +32,104,105,115,97,114,101,97,32,111,102,32,116,104,101,105,115,32,116,104,101,32 +,111,110,108,121,109,111,115,116,32,111,102,32,116,104,101,109,97,110,121,32,111 +,102,32,116,104,101,116,104,101,32,87,101,115,116,101,114,110,84,104,101,114,101 +,32,105,115,32,110,111,101,120,116,101,110,100,101,100,32,116,111,83,116,97,116, +105,115,116,105,99,97,108,99,111,108,115,112,97,110,61,50,32,124,115,104,111,114 +,116,32,115,116,111,114,121,112,111,115,115,105,98,108,101,32,116,111,116,111, +112,111,108,111,103,105,99,97,108,99,114,105,116,105,99,97,108,32,111,102,114, +101,112,111,114,116,101,100,32,116,111,97,32,67,104,114,105,115,116,105,97,110, +100,101,99,105,115,105,111,110,32,116,111,105,115,32,101,113,117,97,108,32,116, +111,112,114,111,98,108,101,109,115,32,111,102,84,104,105,115,32,99,97,110,32,98, +101,109,101,114,99,104,97,110,100,105,115,101,102,111,114,32,109,111,115,116,32, +111,102,110,111,32,101,118,105,100,101,110,99,101,101,100,105,116,105,111,110, +115,32,111,102,101,108,101,109,101,110,116,115,32,105,110,38,113,117,111,116,59, +46,32,84,104,101,99,111,109,47,105,109,97,103,101,115,47,119,104,105,99,104,32, +109,97,107,101,115,116,104,101,32,112,114,111,99,101,115,115,114,101,109,97,105, +110,115,32,116,104,101,108,105,116,101,114,97,116,117,114,101,44,105,115,32,97, +32,109,101,109,98,101,114,116,104,101,32,112,111,112,117,108,97,114,116,104,101, +32,97,110,99,105,101,110,116,112,114,111,98,108,101,109,115,32,105,110,116,105, +109,101,32,111,102,32,116,104,101,100,101,102,101,97,116,101,100,32,98,121,98, +111,100,121,32,111,102,32,116,104,101,97,32,102,101,119,32,121,101,97,114,115, +109,117,99,104,32,111,102,32,116,104,101,116,104,101,32,119,111,114,107,32,111, +102,67,97,108,105,102,111,114,110,105,97,44,115,101,114,118,101,100,32,97,115,32 +,97,103,111,118,101,114,110,109,101,110,116,46,99,111,110,99,101,112,116,115,32, +111,102,109,111,118,101,109,101,110,116,32,105,110,9,9,60,100,105,118,32,105,100 +,61,34,105,116,34,32,118,97,108,117,101,61,34,108,97,110,103,117,97,103,101,32, +111,102,97,115,32,116,104,101,121,32,97,114,101,112,114,111,100,117,99,101,100, +32,105,110,105,115,32,116,104,97,116,32,116,104,101,101,120,112,108,97,105,110, +32,116,104,101,100,105,118,62,60,47,100,105,118,62,10,72,111,119,101,118,101,114 +,32,116,104,101,108,101,97,100,32,116,111,32,116,104,101,9,60,97,32,104,114,101, +102,61,34,47,119,97,115,32,103,114,97,110,116,101,100,112,101,111,112,108,101,32 +,104,97,118,101,99,111,110,116,105,110,117,97,108,108,121,119,97,115,32,115,101, +101,110,32,97,115,97,110,100,32,114,101,108,97,116,101,100,116,104,101,32,114, +111,108,101,32,111,102,112,114,111,112,111,115,101,100,32,98,121,111,102,32,116, +104,101,32,98,101,115,116,101,97,99,104,32,111,116,104,101,114,46,67,111,110,115 +,116,97,110,116,105,110,101,112,101,111,112,108,101,32,102,114,111,109,100,105, +97,108,101,99,116,115,32,111,102,116,111,32,114,101,118,105,115,105,111,110,119, +97,115,32,114,101,110,97,109,101,100,97,32,115,111,117,114,99,101,32,111,102,116 +,104,101,32,105,110,105,116,105,97,108,108,97,117,110,99,104,101,100,32,105,110, +112,114,111,118,105,100,101,32,116,104,101,116,111,32,116,104,101,32,119,101,115 +,116,119,104,101,114,101,32,116,104,101,114,101,97,110,100,32,115,105,109,105, +108,97,114,98,101,116,119,101,101,110,32,116,119,111,105,115,32,97,108,115,111, +32,116,104,101,69,110,103,108,105,115,104,32,97,110,100,99,111,110,100,105,116, +105,111,110,115,44,116,104,97,116,32,105,116,32,119,97,115,101,110,116,105,116, +108,101,100,32,116,111,116,104,101,109,115,101,108,118,101,115,46,113,117,97,110 +,116,105,116,121,32,111,102,114,97,110,115,112,97,114,101,110,99,121,116,104,101 +,32,115,97,109,101,32,97,115,116,111,32,106,111,105,110,32,116,104,101,99,111, +117,110,116,114,121,32,97,110,100,116,104,105,115,32,105,115,32,116,104,101,84, +104,105,115,32,108,101,100,32,116,111,97,32,115,116,97,116,101,109,101,110,116, +99,111,110,116,114,97,115,116,32,116,111,108,97,115,116,73,110,100,101,120,79, +102,116,104,114,111,117,103,104,32,104,105,115,105,115,32,100,101,115,105,103, +110,101,100,116,104,101,32,116,101,114,109,32,105,115,105,115,32,112,114,111,118 +,105,100,101,100,112,114,111,116,101,99,116,32,116,104,101,110,103,60,47,97,62, +60,47,108,105,62,84,104,101,32,99,117,114,114,101,110,116,116,104,101,32,115,105 +,116,101,32,111,102,115,117,98,115,116,97,110,116,105,97,108,101,120,112,101,114 +,105,101,110,99,101,44,105,110,32,116,104,101,32,87,101,115,116,116,104,101,121, +32,115,104,111,117,108,100,115,108,111,118,101,110,196,141,105,110,97,99,111,109 +,101,110,116,97,114,105,111,115,117,110,105,118,101,114,115,105,100,97,100,99, +111,110,100,105,99,105,111,110,101,115,97,99,116,105,118,105,100,97,100,101,115, +101,120,112,101,114,105,101,110,99,105,97,116,101,99,110,111,108,111,103,195,173 +,97,112,114,111,100,117,99,99,105,195,179,110,112,117,110,116,117,97,99,105,195, +179,110,97,112,108,105,99,97,99,105,195,179,110,99,111,110,116,114,97,115,101, +195,177,97,99,97,116,101,103,111,114,195,173,97,115,114,101,103,105,115,116,114, +97,114,115,101,112,114,111,102,101,115,105,111,110,97,108,116,114,97,116,97,109, +105,101,110,116,111,114,101,103,195,173,115,116,114,97,116,101,115,101,99,114, +101,116,97,114,195,173,97,112,114,105,110,99,105,112,97,108,101,115,112,114,111, +116,101,99,99,105,195,179,110,105,109,112,111,114,116,97,110,116,101,115,105,109 +,112,111,114,116,97,110,99,105,97,112,111,115,105,98,105,108,105,100,97,100,105, +110,116,101,114,101,115,97,110,116,101,99,114,101,99,105,109,105,101,110,116,111 +,110,101,99,101,115,105,100,97,100,101,115,115,117,115,99,114,105,98,105,114,115 +,101,97,115,111,99,105,97,99,105,195,179,110,100,105,115,112,111,110,105,98,108, +101,115,101,118,97,108,117,97,99,105,195,179,110,101,115,116,117,100,105,97,110, +116,101,115,114,101,115,112,111,110,115,97,98,108,101,114,101,115,111,108,117,99 +,105,195,179,110,103,117,97,100,97,108,97,106,97,114,97,114,101,103,105,115,116, +114,97,100,111,115,111,112,111,114,116,117,110,105,100,97,100,99,111,109,101,114 +,99,105,97,108,101,115,102,111,116,111,103,114,97,102,195,173,97,97,117,116,111, +114,105,100,97,100,101,115,105,110,103,101,110,105,101,114,195,173,97,116,101, +108,101,118,105,115,105,195,179,110,99,111,109,112,101,116,101,110,99,105,97,111 +,112,101,114,97,99,105,111,110,101,115,101,115,116,97,98,108,101,99,105,100,111, +115,105,109,112,108,101,109,101,110,116,101,97,99,116,117,97,108,109,101,110,116 +,101,110,97,118,101,103,97,99,105,195,179,110,99,111,110,102,111,114,109,105,100 +,97,100,108,105,110,101,45,104,101,105,103,104,116,58,102,111,110,116,45,102,97, +109,105,108,121,58,34,32,58,32,34,104,116,116,112,58,47,47,97,112,112,108,105,99 +,97,116,105,111,110,115,108,105,110,107,34,32,104,114,101,102,61,34,115,112,101, +99,105,102,105,99,97,108,108,121,47,47,60,33,91,67,68,65,84,65,91,10,79,114,103, +97,110,105,122,97,116,105,111,110,100,105,115,116,114,105,98,117,116,105,111,110 +,48,112,120,59,32,104,101,105,103,104,116,58,114,101,108,97,116,105,111,110,115, +104,105,112,100,101,118,105,99,101,45,119,105,100,116,104,60,100,105,118,32,99, +108,97,115,115,61,34,60,108,97,98,101,108,32,102,111,114,61,34,114,101,103,105, +115,116,114,97,116,105,111,110,60,47,110,111,115,99,114,105,112,116,62,10,47,105 +,110,100,101,120,46,104,116,109,108,34,119,105,110,100,111,119,46,111,112,101, +110,40,32,33,105,109,112,111,114,116,97,110,116,59,97,112,112,108,105,99,97,116, +105,111,110,47,105,110,100,101,112,101,110,100,101,110,99,101,47,47,119,119,119, +46,103,111,111,103,108,101,111,114,103,97,110,105,122,97,116,105,111,110,97,117, +116,111,99,111,109,112,108,101,116,101,114,101,113,117,105,114,101,109,101,110, +116,115,99,111,110,115,101,114,118,97,116,105,118,101,60,102,111,114,109,32,110, +97,109,101,61,34,105,110,116,101,108,108,101,99,116,117,97,108,109,97,114,103, +105,110,45,108,101,102,116,58,49,56,116,104,32,99,101,110,116,117,114,121,97,110 +,32,105,109,112,111,114,116,97,110,116,105,110,115,116,105,116,117,116,105,111, +110,115,97,98,98,114,101,118,105,97,116,105,111,110,60,105,109,103,32,99,108,97, +115,115,61,34,111,114,103,97,110,105,115,97,116,105,111,110,99,105,118,105,108, +105,122,97,116,105,111,110,49,57,116,104,32,99,101,110,116,117,114,121,97,114,99 +,104,105,116,101,99,116,117,114,101,105,110,99,111,114,112,111,114,97,116,101, +100,50,48,116,104,32,99,101,110,116,117,114,121,45,99,111,110,116,97,105,110,101 +,114,34,62,109,111,115,116,32,110,111,116,97,98,108,121,47,62,60,47,97,62,60,47, +100,105,118,62,110,111,116,105,102,105,99,97,116,105,111,110,39,117,110,100,101, +102,105,110,101,100,39,41,70,117,114,116,104,101,114,109,111,114,101,44,98,101, +108,105,101,118,101,32,116,104,97,116,105,110,110,101,114,72,84,77,76,32,61,32, +112,114,105,111,114,32,116,111,32,116,104,101,100,114,97,109,97,116,105,99,97, +108,108,121,114,101,102,101,114,114,105,110,103,32,116,111,110,101,103,111,116, +105,97,116,105,111,110,115,104,101,97,100,113,117,97,114,116,101,114,115,83,111, +117,116,104,32,65,102,114,105,99,97,117,110,115,117,99,99,101,115,115,102,117, +108,80,101,110,110,115,121,108,118,97,110,105,97,65,115,32,97,32,114,101,115,117 +,108,116,44,60,104,116,109,108,32,108,97,110,103,61,34,38,108,116,59,47,115,117, +112,38,103,116,59,100,101,97,108,105,110,103,32,119,105,116,104,112,104,105,108, +97,100,101,108,112,104,105,97,104,105,115,116,111,114,105,99,97,108,108,121,41, +59,60,47,115,99,114,105,112,116,62,10,112,97,100,100,105,110,103,45,116,111,112, +58,101,120,112,101,114,105,109,101,110,116,97,108,103,101,116,65,116,116,114,105 +,98,117,116,101,105,110,115,116,114,117,99,116,105,111,110,115,116,101,99,104, +110,111,108,111,103,105,101,115,112,97,114,116,32,111,102,32,116,104,101,32,61, +102,117,110,99,116,105,111,110,40,41,123,115,117,98,115,99,114,105,112,116,105, +111,110,108,46,100,116,100,34,62,13,10,60,104,116,103,101,111,103,114,97,112,104 +,105,99,97,108,67,111,110,115,116,105,116,117,116,105,111,110,39,44,32,102,117, +110,99,116,105,111,110,40,115,117,112,112,111,114,116,101,100,32,98,121,97,103, +114,105,99,117,108,116,117,114,97,108,99,111,110,115,116,114,117,99,116,105,111, +110,112,117,98,108,105,99,97,116,105,111,110,115,102,111,110,116,45,115,105,122, +101,58,32,49,97,32,118,97,114,105,101,116,121,32,111,102,60,100,105,118,32,115, +116,121,108,101,61,34,69,110,99,121,99,108,111,112,101,100,105,97,105,102,114,97 +,109,101,32,115,114,99,61,34,100,101,109,111,110,115,116,114,97,116,101,100,97, +99,99,111,109,112,108,105,115,104,101,100,117,110,105,118,101,114,115,105,116, +105,101,115,68,101,109,111,103,114,97,112,104,105,99,115,41,59,60,47,115,99,114, +105,112,116,62,60,100,101,100,105,99,97,116,101,100,32,116,111,107,110,111,119, +108,101,100,103,101,32,111,102,115,97,116,105,115,102,97,99,116,105,111,110,112, +97,114,116,105,99,117,108,97,114,108,121,60,47,100,105,118,62,60,47,100,105,118, +62,69,110,103,108,105,115,104,32,40,85,83,41,97,112,112,101,110,100,67,104,105, +108,100,40,116,114,97,110,115,109,105,115,115,105,111,110,115,46,32,72,111,119, +101,118,101,114,44,32,105,110,116,101,108,108,105,103,101,110,99,101,34,32,116, +97,98,105,110,100,101,120,61,34,102,108,111,97,116,58,114,105,103,104,116,59,67, +111,109,109,111,110,119,101,97,108,116,104,114,97,110,103,105,110,103,32,102,114 +,111,109,105,110,32,119,104,105,99,104,32,116,104,101,97,116,32,108,101,97,115, +116,32,111,110,101,114,101,112,114,111,100,117,99,116,105,111,110,101,110,99,121 +,99,108,111,112,101,100,105,97,59,102,111,110,116,45,115,105,122,101,58,49,106, +117,114,105,115,100,105,99,116,105,111,110,97,116,32,116,104,97,116,32,116,105, +109,101,34,62,60,97,32,99,108,97,115,115,61,34,73,110,32,97,100,100,105,116,105, +111,110,44,100,101,115,99,114,105,112,116,105,111,110,43,99,111,110,118,101,114, +115,97,116,105,111,110,99,111,110,116,97,99,116,32,119,105,116,104,105,115,32, +103,101,110,101,114,97,108,108,121,114,34,32,99,111,110,116,101,110,116,61,34, +114,101,112,114,101,115,101,110,116,105,110,103,38,108,116,59,109,97,116,104,38, +103,116,59,112,114,101,115,101,110,116,97,116,105,111,110,111,99,99,97,115,105, +111,110,97,108,108,121,60,105,109,103,32,119,105,100,116,104,61,34,110,97,118, +105,103,97,116,105,111,110,34,62,99,111,109,112,101,110,115,97,116,105,111,110, +99,104,97,109,112,105,111,110,115,104,105,112,109,101,100,105,97,61,34,97,108, +108,34,32,118,105,111,108,97,116,105,111,110,32,111,102,114,101,102,101,114,101, +110,99,101,32,116,111,114,101,116,117,114,110,32,116,114,117,101,59,83,116,114, +105,99,116,47,47,69,78,34,32,116,114,97,110,115,97,99,116,105,111,110,115,105, +110,116,101,114,118,101,110,116,105,111,110,118,101,114,105,102,105,99,97,116, +105,111,110,73,110,102,111,114,109,97,116,105,111,110,32,100,105,102,102,105,99, +117,108,116,105,101,115,67,104,97,109,112,105,111,110,115,104,105,112,99,97,112, +97,98,105,108,105,116,105,101,115,60,33,91,101,110,100,105,102,93,45,45,62,125, +10,60,47,115,99,114,105,112,116,62,10,67,104,114,105,115,116,105,97,110,105,116, +121,102,111,114,32,101,120,97,109,112,108,101,44,80,114,111,102,101,115,115,105, +111,110,97,108,114,101,115,116,114,105,99,116,105,111,110,115,115,117,103,103, +101,115,116,32,116,104,97,116,119,97,115,32,114,101,108,101,97,115,101,100,40, +115,117,99,104,32,97,115,32,116,104,101,114,101,109,111,118,101,67,108,97,115, +115,40,117,110,101,109,112,108,111,121,109,101,110,116,116,104,101,32,65,109,101 +,114,105,99,97,110,115,116,114,117,99,116,117,114,101,32,111,102,47,105,110,100, +101,120,46,104,116,109,108,32,112,117,98,108,105,115,104,101,100,32,105,110,115, +112,97,110,32,99,108,97,115,115,61,34,34,62,60,97,32,104,114,101,102,61,34,47, +105,110,116,114,111,100,117,99,116,105,111,110,98,101,108,111,110,103,105,110, +103,32,116,111,99,108,97,105,109,101,100,32,116,104,97,116,99,111,110,115,101, +113,117,101,110,99,101,115,60,109,101,116,97,32,110,97,109,101,61,34,71,117,105, +100,101,32,116,111,32,116,104,101,111,118,101,114,119,104,101,108,109,105,110, +103,97,103,97,105,110,115,116,32,116,104,101,32,99,111,110,99,101,110,116,114,97 +,116,101,100,44,10,46,110,111,110,116,111,117,99,104,32,111,98,115,101,114,118, +97,116,105,111,110,115,60,47,97,62,10,60,47,100,105,118,62,10,102,32,40,100,111, +99,117,109,101,110,116,46,98,111,114,100,101,114,58,32,49,112,120,32,123,102,111 +,110,116,45,115,105,122,101,58,49,116,114,101,97,116,109,101,110,116,32,111,102, +48,34,32,104,101,105,103,104,116,61,34,49,109,111,100,105,102,105,99,97,116,105, +111,110,73,110,100,101,112,101,110,100,101,110,99,101,100,105,118,105,100,101, +100,32,105,110,116,111,103,114,101,97,116,101,114,32,116,104,97,110,97,99,104, +105,101,118,101,109,101,110,116,115,101,115,116,97,98,108,105,115,104,105,110, +103,74,97,118,97,83,99,114,105,112,116,34,32,110,101,118,101,114,116,104,101,108 +,101,115,115,115,105,103,110,105,102,105,99,97,110,99,101,66,114,111,97,100,99, +97,115,116,105,110,103,62,38,110,98,115,112,59,60,47,116,100,62,99,111,110,116, +97,105,110,101,114,34,62,10,115,117,99,104,32,97,115,32,116,104,101,32,105,110, +102,108,117,101,110,99,101,32,111,102,97,32,112,97,114,116,105,99,117,108,97,114 +,115,114,99,61,39,104,116,116,112,58,47,47,110,97,118,105,103,97,116,105,111,110 +,34,32,104,97,108,102,32,111,102,32,116,104,101,32,115,117,98,115,116,97,110,116 +,105,97,108,32,38,110,98,115,112,59,60,47,100,105,118,62,97,100,118,97,110,116, +97,103,101,32,111,102,100,105,115,99,111,118,101,114,121,32,111,102,102,117,110, +100,97,109,101,110,116,97,108,32,109,101,116,114,111,112,111,108,105,116,97,110, +116,104,101,32,111,112,112,111,115,105,116,101,34,32,120,109,108,58,108,97,110, +103,61,34,100,101,108,105,98,101,114,97,116,101,108,121,97,108,105,103,110,61,99 +,101,110,116,101,114,101,118,111,108,117,116,105,111,110,32,111,102,112,114,101, +115,101,114,118,97,116,105,111,110,105,109,112,114,111,118,101,109,101,110,116, +115,98,101,103,105,110,110,105,110,103,32,105,110,74,101,115,117,115,32,67,104, +114,105,115,116,80,117,98,108,105,99,97,116,105,111,110,115,100,105,115,97,103, +114,101,101,109,101,110,116,116,101,120,116,45,97,108,105,103,110,58,114,44,32, +102,117,110,99,116,105,111,110,40,41,115,105,109,105,108,97,114,105,116,105,101, +115,98,111,100,121,62,60,47,104,116,109,108,62,105,115,32,99,117,114,114,101,110 +,116,108,121,97,108,112,104,97,98,101,116,105,99,97,108,105,115,32,115,111,109, +101,116,105,109,101,115,116,121,112,101,61,34,105,109,97,103,101,47,109,97,110, +121,32,111,102,32,116,104,101,32,102,108,111,119,58,104,105,100,100,101,110,59, +97,118,97,105,108,97,98,108,101,32,105,110,100,101,115,99,114,105,98,101,32,116, +104,101,101,120,105,115,116,101,110,99,101,32,111,102,97,108,108,32,111,118,101, +114,32,116,104,101,116,104,101,32,73,110,116,101,114,110,101,116,9,60,117,108,32 +,99,108,97,115,115,61,34,105,110,115,116,97,108,108,97,116,105,111,110,110,101, +105,103,104,98,111,114,104,111,111,100,97,114,109,101,100,32,102,111,114,99,101, +115,114,101,100,117,99,105,110,103,32,116,104,101,99,111,110,116,105,110,117,101 +,115,32,116,111,78,111,110,101,116,104,101,108,101,115,115,44,116,101,109,112, +101,114,97,116,117,114,101,115,10,9,9,60,97,32,104,114,101,102,61,34,99,108,111, +115,101,32,116,111,32,116,104,101,101,120,97,109,112,108,101,115,32,111,102,32, +105,115,32,97,98,111,117,116,32,116,104,101,40,115,101,101,32,98,101,108,111,119 +,41,46,34,32,105,100,61,34,115,101,97,114,99,104,112,114,111,102,101,115,115,105 +,111,110,97,108,105,115,32,97,118,97,105,108,97,98,108,101,116,104,101,32,111, +102,102,105,99,105,97,108,9,9,60,47,115,99,114,105,112,116,62,10,10,9,9,60,100, +105,118,32,105,100,61,34,97,99,99,101,108,101,114,97,116,105,111,110,116,104,114 +,111,117,103,104,32,116,104,101,32,72,97,108,108,32,111,102,32,70,97,109,101,100 +,101,115,99,114,105,112,116,105,111,110,115,116,114,97,110,115,108,97,116,105, +111,110,115,105,110,116,101,114,102,101,114,101,110,99,101,32,116,121,112,101,61 +,39,116,101,120,116,47,114,101,99,101,110,116,32,121,101,97,114,115,105,110,32, +116,104,101,32,119,111,114,108,100,118,101,114,121,32,112,111,112,117,108,97,114 +,123,98,97,99,107,103,114,111,117,110,100,58,116,114,97,100,105,116,105,111,110, +97,108,32,115,111,109,101,32,111,102,32,116,104,101,32,99,111,110,110,101,99,116 +,101,100,32,116,111,101,120,112,108,111,105,116,97,116,105,111,110,101,109,101, +114,103,101,110,99,101,32,111,102,99,111,110,115,116,105,116,117,116,105,111,110 +,65,32,72,105,115,116,111,114,121,32,111,102,115,105,103,110,105,102,105,99,97, +110,116,32,109,97,110,117,102,97,99,116,117,114,101,100,101,120,112,101,99,116, +97,116,105,111,110,115,62,60,110,111,115,99,114,105,112,116,62,60,99,97,110,32, +98,101,32,102,111,117,110,100,98,101,99,97,117,115,101,32,116,104,101,32,104,97, +115,32,110,111,116,32,98,101,101,110,110,101,105,103,104,98,111,117,114,105,110, +103,119,105,116,104,111,117,116,32,116,104,101,32,97,100,100,101,100,32,116,111, +32,116,104,101,9,60,108,105,32,99,108,97,115,115,61,34,105,110,115,116,114,117, +109,101,110,116,97,108,83,111,118,105,101,116,32,85,110,105,111,110,97,99,107, +110,111,119,108,101,100,103,101,100,119,104,105,99,104,32,99,97,110,32,98,101, +110,97,109,101,32,102,111,114,32,116,104,101,97,116,116,101,110,116,105,111,110, +32,116,111,97,116,116,101,109,112,116,115,32,116,111,32,100,101,118,101,108,111, +112,109,101,110,116,115,73,110,32,102,97,99,116,44,32,116,104,101,60,108,105,32, +99,108,97,115,115,61,34,97,105,109,112,108,105,99,97,116,105,111,110,115,115,117 +,105,116,97,98,108,101,32,102,111,114,109,117,99,104,32,111,102,32,116,104,101, +32,99,111,108,111,110,105,122,97,116,105,111,110,112,114,101,115,105,100,101,110 +,116,105,97,108,99,97,110,99,101,108,66,117,98,98,108,101,32,73,110,102,111,114, +109,97,116,105,111,110,109,111,115,116,32,111,102,32,116,104,101,32,105,115,32, +100,101,115,99,114,105,98,101,100,114,101,115,116,32,111,102,32,116,104,101,32, +109,111,114,101,32,111,114,32,108,101,115,115,105,110,32,83,101,112,116,101,109, +98,101,114,73,110,116,101,108,108,105,103,101,110,99,101,115,114,99,61,34,104, +116,116,112,58,47,47,112,120,59,32,104,101,105,103,104,116,58,32,97,118,97,105, +108,97,98,108,101,32,116,111,109,97,110,117,102,97,99,116,117,114,101,114,104, +117,109,97,110,32,114,105,103,104,116,115,108,105,110,107,32,104,114,101,102,61, +34,47,97,118,97,105,108,97,98,105,108,105,116,121,112,114,111,112,111,114,116, +105,111,110,97,108,111,117,116,115,105,100,101,32,116,104,101,32,97,115,116,114, +111,110,111,109,105,99,97,108,104,117,109,97,110,32,98,101,105,110,103,115,110, +97,109,101,32,111,102,32,116,104,101,32,97,114,101,32,102,111,117,110,100,32,105 +,110,97,114,101,32,98,97,115,101,100,32,111,110,115,109,97,108,108,101,114,32, +116,104,97,110,97,32,112,101,114,115,111,110,32,119,104,111,101,120,112,97,110, +115,105,111,110,32,111,102,97,114,103,117,105,110,103,32,116,104,97,116,110,111, +119,32,107,110,111,119,110,32,97,115,73,110,32,116,104,101,32,101,97,114,108,121 +,105,110,116,101,114,109,101,100,105,97,116,101,100,101,114,105,118,101,100,32, +102,114,111,109,83,99,97,110,100,105,110,97,118,105,97,110,60,47,97,62,60,47,100 +,105,118,62,13,10,99,111,110,115,105,100,101,114,32,116,104,101,97,110,32,101, +115,116,105,109,97,116,101,100,116,104,101,32,78,97,116,105,111,110,97,108,60, +100,105,118,32,105,100,61,34,112,97,103,114,101,115,117,108,116,105,110,103,32, +105,110,99,111,109,109,105,115,115,105,111,110,101,100,97,110,97,108,111,103,111 +,117,115,32,116,111,97,114,101,32,114,101,113,117,105,114,101,100,47,117,108,62, +10,60,47,100,105,118,62,10,119,97,115,32,98,97,115,101,100,32,111,110,97,110,100 +,32,98,101,99,97,109,101,32,97,38,110,98,115,112,59,38,110,98,115,112,59,116,34, +32,118,97,108,117,101,61,34,34,32,119,97,115,32,99,97,112,116,117,114,101,100, +110,111,32,109,111,114,101,32,116,104,97,110,114,101,115,112,101,99,116,105,118, +101,108,121,99,111,110,116,105,110,117,101,32,116,111,32,62,13,10,60,104,101,97, +100,62,13,10,60,119,101,114,101,32,99,114,101,97,116,101,100,109,111,114,101,32, +103,101,110,101,114,97,108,105,110,102,111,114,109,97,116,105,111,110,32,117,115 +,101,100,32,102,111,114,32,116,104,101,105,110,100,101,112,101,110,100,101,110, +116,32,116,104,101,32,73,109,112,101,114,105,97,108,99,111,109,112,111,110,101, +110,116,32,111,102,116,111,32,116,104,101,32,110,111,114,116,104,105,110,99,108, +117,100,101,32,116,104,101,32,67,111,110,115,116,114,117,99,116,105,111,110,115, +105,100,101,32,111,102,32,116,104,101,32,119,111,117,108,100,32,110,111,116,32, +98,101,102,111,114,32,105,110,115,116,97,110,99,101,105,110,118,101,110,116,105, +111,110,32,111,102,109,111,114,101,32,99,111,109,112,108,101,120,99,111,108,108, +101,99,116,105,118,101,108,121,98,97,99,107,103,114,111,117,110,100,58,32,116, +101,120,116,45,97,108,105,103,110,58,32,105,116,115,32,111,114,105,103,105,110, +97,108,105,110,116,111,32,97,99,99,111,117,110,116,116,104,105,115,32,112,114, +111,99,101,115,115,97,110,32,101,120,116,101,110,115,105,118,101,104,111,119,101 +,118,101,114,44,32,116,104,101,116,104,101,121,32,97,114,101,32,110,111,116,114, +101,106,101,99,116,101,100,32,116,104,101,99,114,105,116,105,99,105,115,109,32, +111,102,100,117,114,105,110,103,32,119,104,105,99,104,112,114,111,98,97,98,108, +121,32,116,104,101,116,104,105,115,32,97,114,116,105,99,108,101,40,102,117,110, +99,116,105,111,110,40,41,123,73,116,32,115,104,111,117,108,100,32,98,101,97,110, +32,97,103,114,101,101,109,101,110,116,97,99,99,105,100,101,110,116,97,108,108, +121,100,105,102,102,101,114,115,32,102,114,111,109,65,114,99,104,105,116,101,99, +116,117,114,101,98,101,116,116,101,114,32,107,110,111,119,110,97,114,114,97,110, +103,101,109,101,110,116,115,105,110,102,108,117,101,110,99,101,32,111,110,97,116 +,116,101,110,100,101,100,32,116,104,101,105,100,101,110,116,105,99,97,108,32,116 +,111,115,111,117,116,104,32,111,102,32,116,104,101,112,97,115,115,32,116,104,114 +,111,117,103,104,120,109,108,34,32,116,105,116,108,101,61,34,119,101,105,103,104 +,116,58,98,111,108,100,59,99,114,101,97,116,105,110,103,32,116,104,101,100,105, +115,112,108,97,121,58,110,111,110,101,114,101,112,108,97,99,101,100,32,116,104, +101,60,105,109,103,32,115,114,99,61,34,47,105,104,116,116,112,115,58,47,47,119, +119,119,46,87,111,114,108,100,32,87,97,114,32,73,73,116,101,115,116,105,109,111, +110,105,97,108,115,102,111,117,110,100,32,105,110,32,116,104,101,114,101,113,117 +,105,114,101,100,32,116,111,32,97,110,100,32,116,104,97,116,32,116,104,101,98, +101,116,119,101,101,110,32,116,104,101,32,119,97,115,32,100,101,115,105,103,110, +101,100,99,111,110,115,105,115,116,115,32,111,102,32,99,111,110,115,105,100,101, +114,97,98,108,121,112,117,98,108,105,115,104,101,100,32,98,121,116,104,101,32, +108,97,110,103,117,97,103,101,67,111,110,115,101,114,118,97,116,105,111,110,99, +111,110,115,105,115,116,101,100,32,111,102,114,101,102,101,114,32,116,111,32,116 +,104,101,98,97,99,107,32,116,111,32,116,104,101,32,99,115,115,34,32,109,101,100, +105,97,61,34,80,101,111,112,108,101,32,102,114,111,109,32,97,118,97,105,108,97, +98,108,101,32,111,110,112,114,111,118,101,100,32,116,111,32,98,101,115,117,103, +103,101,115,116,105,111,110,115,34,119,97,115,32,107,110,111,119,110,32,97,115, +118,97,114,105,101,116,105,101,115,32,111,102,108,105,107,101,108,121,32,116,111 +,32,98,101,99,111,109,112,114,105,115,101,100,32,111,102,115,117,112,112,111,114 +,116,32,116,104,101,32,104,97,110,100,115,32,111,102,32,116,104,101,99,111,117, +112,108,101,100,32,119,105,116,104,99,111,110,110,101,99,116,32,97,110,100,32,98 +,111,114,100,101,114,58,110,111,110,101,59,112,101,114,102,111,114,109,97,110,99 +,101,115,98,101,102,111,114,101,32,98,101,105,110,103,108,97,116,101,114,32,98, +101,99,97,109,101,99,97,108,99,117,108,97,116,105,111,110,115,111,102,116,101, +110,32,99,97,108,108,101,100,114,101,115,105,100,101,110,116,115,32,111,102,109, +101,97,110,105,110,103,32,116,104,97,116,62,60,108,105,32,99,108,97,115,115,61, +34,101,118,105,100,101,110,99,101,32,102,111,114,101,120,112,108,97,110,97,116, +105,111,110,115,101,110,118,105,114,111,110,109,101,110,116,115,34,62,60,47,97, +62,60,47,100,105,118,62,119,104,105,99,104,32,97,108,108,111,119,115,73,110,116, +114,111,100,117,99,116,105,111,110,100,101,118,101,108,111,112,101,100,32,98,121 +,97,32,119,105,100,101,32,114,97,110,103,101,111,110,32,98,101,104,97,108,102,32 +,111,102,118,97,108,105,103,110,61,34,116,111,112,34,112,114,105,110,99,105,112, +108,101,32,111,102,97,116,32,116,104,101,32,116,105,109,101,44,60,47,110,111,115 +,99,114,105,112,116,62,13,115,97,105,100,32,116,111,32,104,97,118,101,105,110,32 +,116,104,101,32,102,105,114,115,116,119,104,105,108,101,32,111,116,104,101,114, +115,104,121,112,111,116,104,101,116,105,99,97,108,112,104,105,108,111,115,111, +112,104,101,114,115,112,111,119,101,114,32,111,102,32,116,104,101,99,111,110,116 +,97,105,110,101,100,32,105,110,112,101,114,102,111,114,109,101,100,32,98,121,105 +,110,97,98,105,108,105,116,121,32,116,111,119,101,114,101,32,119,114,105,116,116 +,101,110,115,112,97,110,32,115,116,121,108,101,61,34,105,110,112,117,116,32,110, +97,109,101,61,34,116,104,101,32,113,117,101,115,116,105,111,110,105,110,116,101, +110,100,101,100,32,102,111,114,114,101,106,101,99,116,105,111,110,32,111,102,105 +,109,112,108,105,101,115,32,116,104,97,116,105,110,118,101,110,116,101,100,32, +116,104,101,116,104,101,32,115,116,97,110,100,97,114,100,119,97,115,32,112,114, +111,98,97,98,108,121,108,105,110,107,32,98,101,116,119,101,101,110,112,114,111, +102,101,115,115,111,114,32,111,102,105,110,116,101,114,97,99,116,105,111,110,115 +,99,104,97,110,103,105,110,103,32,116,104,101,73,110,100,105,97,110,32,79,99,101 +,97,110,32,99,108,97,115,115,61,34,108,97,115,116,119,111,114,107,105,110,103,32 +,119,105,116,104,39,104,116,116,112,58,47,47,119,119,119,46,121,101,97,114,115, +32,98,101,102,111,114,101,84,104,105,115,32,119,97,115,32,116,104,101,114,101,99 +,114,101,97,116,105,111,110,97,108,101,110,116,101,114,105,110,103,32,116,104, +101,109,101,97,115,117,114,101,109,101,110,116,115,97,110,32,101,120,116,114,101 +,109,101,108,121,118,97,108,117,101,32,111,102,32,116,104,101,115,116,97,114,116 +,32,111,102,32,116,104,101,10,60,47,115,99,114,105,112,116,62,10,10,97,110,32, +101,102,102,111,114,116,32,116,111,105,110,99,114,101,97,115,101,32,116,104,101, +116,111,32,116,104,101,32,115,111,117,116,104,115,112,97,99,105,110,103,61,34,48 +,34,62,115,117,102,102,105,99,105,101,110,116,108,121,116,104,101,32,69,117,114, +111,112,101,97,110,99,111,110,118,101,114,116,101,100,32,116,111,99,108,101,97, +114,84,105,109,101,111,117,116,100,105,100,32,110,111,116,32,104,97,118,101,99, +111,110,115,101,113,117,101,110,116,108,121,102,111,114,32,116,104,101,32,110, +101,120,116,101,120,116,101,110,115,105,111,110,32,111,102,101,99,111,110,111, +109,105,99,32,97,110,100,97,108,116,104,111,117,103,104,32,116,104,101,97,114, +101,32,112,114,111,100,117,99,101,100,97,110,100,32,119,105,116,104,32,116,104, +101,105,110,115,117,102,102,105,99,105,101,110,116,103,105,118,101,110,32,98,121 +,32,116,104,101,115,116,97,116,105,110,103,32,116,104,97,116,101,120,112,101,110 +,100,105,116,117,114,101,115,60,47,115,112,97,110,62,60,47,97,62,10,116,104,111, +117,103,104,116,32,116,104,97,116,111,110,32,116,104,101,32,98,97,115,105,115,99 +,101,108,108,112,97,100,100,105,110,103,61,105,109,97,103,101,32,111,102,32,116, +104,101,114,101,116,117,114,110,105,110,103,32,116,111,105,110,102,111,114,109, +97,116,105,111,110,44,115,101,112,97,114,97,116,101,100,32,98,121,97,115,115,97, +115,115,105,110,97,116,101,100,115,34,32,99,111,110,116,101,110,116,61,34,97,117 +,116,104,111,114,105,116,121,32,111,102,110,111,114,116,104,119,101,115,116,101, +114,110,60,47,100,105,118,62,10,60,100,105,118,32,34,62,60,47,100,105,118,62,13, +10,32,32,99,111,110,115,117,108,116,97,116,105,111,110,99,111,109,109,117,110, +105,116,121,32,111,102,116,104,101,32,110,97,116,105,111,110,97,108,105,116,32, +115,104,111,117,108,100,32,98,101,112,97,114,116,105,99,105,112,97,110,116,115, +32,97,108,105,103,110,61,34,108,101,102,116,116,104,101,32,103,114,101,97,116, +101,115,116,115,101,108,101,99,116,105,111,110,32,111,102,115,117,112,101,114, +110,97,116,117,114,97,108,100,101,112,101,110,100,101,110,116,32,111,110,105,115 +,32,109,101,110,116,105,111,110,101,100,97,108,108,111,119,105,110,103,32,116, +104,101,119,97,115,32,105,110,118,101,110,116,101,100,97,99,99,111,109,112,97, +110,121,105,110,103,104,105,115,32,112,101,114,115,111,110,97,108,97,118,97,105, +108,97,98,108,101,32,97,116,115,116,117,100,121,32,111,102,32,116,104,101,111, +110,32,116,104,101,32,111,116,104,101,114,101,120,101,99,117,116,105,111,110,32, +111,102,72,117,109,97,110,32,82,105,103,104,116,115,116,101,114,109,115,32,111, +102,32,116,104,101,97,115,115,111,99,105,97,116,105,111,110,115,114,101,115,101, +97,114,99,104,32,97,110,100,115,117,99,99,101,101,100,101,100,32,98,121,100,101, +102,101,97,116,101,100,32,116,104,101,97,110,100,32,102,114,111,109,32,116,104, +101,98,117,116,32,116,104,101,121,32,97,114,101,99,111,109,109,97,110,100,101, +114,32,111,102,115,116,97,116,101,32,111,102,32,116,104,101,121,101,97,114,115, +32,111,102,32,97,103,101,116,104,101,32,115,116,117,100,121,32,111,102,60,117, +108,32,99,108,97,115,115,61,34,115,112,108,97,99,101,32,105,110,32,116,104,101, +119,104,101,114,101,32,104,101,32,119,97,115,60,108,105,32,99,108,97,115,115,61, +34,102,116,104,101,114,101,32,97,114,101,32,110,111,119,104,105,99,104,32,98,101 +,99,97,109,101,104,101,32,112,117,98,108,105,115,104,101,100,101,120,112,114,101 +,115,115,101,100,32,105,110,116,111,32,119,104,105,99,104,32,116,104,101,99,111, +109,109,105,115,115,105,111,110,101,114,102,111,110,116,45,119,101,105,103,104, +116,58,116,101,114,114,105,116,111,114,121,32,111,102,101,120,116,101,110,115, +105,111,110,115,34,62,82,111,109,97,110,32,69,109,112,105,114,101,101,113,117,97 +,108,32,116,111,32,116,104,101,73,110,32,99,111,110,116,114,97,115,116,44,104, +111,119,101,118,101,114,44,32,97,110,100,105,115,32,116,121,112,105,99,97,108, +108,121,97,110,100,32,104,105,115,32,119,105,102,101,40,97,108,115,111,32,99,97, +108,108,101,100,62,60,117,108,32,99,108,97,115,115,61,34,101,102,102,101,99,116, +105,118,101,108,121,32,101,118,111,108,118,101,100,32,105,110,116,111,115,101, +101,109,32,116,111,32,104,97,118,101,119,104,105,99,104,32,105,115,32,116,104, +101,116,104,101,114,101,32,119,97,115,32,110,111,97,110,32,101,120,99,101,108, +108,101,110,116,97,108,108,32,111,102,32,116,104,101,115,101,100,101,115,99,114, +105,98,101,100,32,98,121,73,110,32,112,114,97,99,116,105,99,101,44,98,114,111,97 +,100,99,97,115,116,105,110,103,99,104,97,114,103,101,100,32,119,105,116,104,114, +101,102,108,101,99,116,101,100,32,105,110,115,117,98,106,101,99,116,101,100,32, +116,111,109,105,108,105,116,97,114,121,32,97,110,100,116,111,32,116,104,101,32, +112,111,105,110,116,101,99,111,110,111,109,105,99,97,108,108,121,115,101,116,84, +97,114,103,101,116,105,110,103,97,114,101,32,97,99,116,117,97,108,108,121,118, +105,99,116,111,114,121,32,111,118,101,114,40,41,59,60,47,115,99,114,105,112,116, +62,99,111,110,116,105,110,117,111,117,115,108,121,114,101,113,117,105,114,101, +100,32,102,111,114,101,118,111,108,117,116,105,111,110,97,114,121,97,110,32,101, +102,102,101,99,116,105,118,101,110,111,114,116,104,32,111,102,32,116,104,101,44, +32,119,104,105,99,104,32,119,97,115,32,102,114,111,110,116,32,111,102,32,116,104 +,101,111,114,32,111,116,104,101,114,119,105,115,101,115,111,109,101,32,102,111, +114,109,32,111,102,104,97,100,32,110,111,116,32,98,101,101,110,103,101,110,101, +114,97,116,101,100,32,98,121,105,110,102,111,114,109,97,116,105,111,110,46,112, +101,114,109,105,116,116,101,100,32,116,111,105,110,99,108,117,100,101,115,32,116 +,104,101,100,101,118,101,108,111,112,109,101,110,116,44,101,110,116,101,114,101, +100,32,105,110,116,111,116,104,101,32,112,114,101,118,105,111,117,115,99,111,110 +,115,105,115,116,101,110,116,108,121,97,114,101,32,107,110,111,119,110,32,97,115 +,116,104,101,32,102,105,101,108,100,32,111,102,116,104,105,115,32,116,121,112, +101,32,111,102,103,105,118,101,110,32,116,111,32,116,104,101,116,104,101,32,116, +105,116,108,101,32,111,102,99,111,110,116,97,105,110,115,32,116,104,101,105,110, +115,116,97,110,99,101,115,32,111,102,105,110,32,116,104,101,32,110,111,114,116, +104,100,117,101,32,116,111,32,116,104,101,105,114,97,114,101,32,100,101,115,105, +103,110,101,100,99,111,114,112,111,114,97,116,105,111,110,115,119,97,115,32,116, +104,97,116,32,116,104,101,111,110,101,32,111,102,32,116,104,101,115,101,109,111, +114,101,32,112,111,112,117,108,97,114,115,117,99,99,101,101,100,101,100,32,105, +110,115,117,112,112,111,114,116,32,102,114,111,109,105,110,32,100,105,102,102, +101,114,101,110,116,100,111,109,105,110,97,116,101,100,32,98,121,100,101,115,105 +,103,110,101,100,32,102,111,114,111,119,110,101,114,115,104,105,112,32,111,102, +97,110,100,32,112,111,115,115,105,98,108,121,115,116,97,110,100,97,114,100,105, +122,101,100,114,101,115,112,111,110,115,101,84,101,120,116,119,97,115,32,105,110 +,116,101,110,100,101,100,114,101,99,101,105,118,101,100,32,116,104,101,97,115, +115,117,109,101,100,32,116,104,97,116,97,114,101,97,115,32,111,102,32,116,104, +101,112,114,105,109,97,114,105,108,121,32,105,110,116,104,101,32,98,97,115,105, +115,32,111,102,105,110,32,116,104,101,32,115,101,110,115,101,97,99,99,111,117, +110,116,115,32,102,111,114,100,101,115,116,114,111,121,101,100,32,98,121,97,116, +32,108,101,97,115,116,32,116,119,111,119,97,115,32,100,101,99,108,97,114,101,100 +,99,111,117,108,100,32,110,111,116,32,98,101,83,101,99,114,101,116,97,114,121,32 +,111,102,97,112,112,101,97,114,32,116,111,32,98,101,109,97,114,103,105,110,45, +116,111,112,58,49,47,94,92,115,43,124,92,115,43,36,47,103,101,41,123,116,104,114 +,111,119,32,101,125,59,116,104,101,32,115,116,97,114,116,32,111,102,116,119,111, +32,115,101,112,97,114,97,116,101,108,97,110,103,117,97,103,101,32,97,110,100,119 +,104,111,32,104,97,100,32,98,101,101,110,111,112,101,114,97,116,105,111,110,32, +111,102,100,101,97,116,104,32,111,102,32,116,104,101,114,101,97,108,32,110,117, +109,98,101,114,115,9,60,108,105,110,107,32,114,101,108,61,34,112,114,111,118,105 +,100,101,100,32,116,104,101,116,104,101,32,115,116,111,114,121,32,111,102,99,111 +,109,112,101,116,105,116,105,111,110,115,101,110,103,108,105,115,104,32,40,85,75 +,41,101,110,103,108,105,115,104,32,40,85,83,41,208,156,208,190,208,189,208,179, +208,190,208,187,208,161,209,128,208,191,209,129,208,186,208,184,209,129,209,128, +208,191,209,129,208,186,208,184,209,129,209,128,208,191,209,129,208,186,208,190, +217,132,216,185,216,177,216,168,217,138,216,169,230,173,163,233,171,148,228,184, +173,230,150,135,231,174,128,228,189,147,228,184,173,230,150,135,231,185,129,228, +189,147,228,184,173,230,150,135,230,156,137,233,153,144,229,133,172,229,143,184, +228,186,186,230,176,145,230,148,191,229,186,156,233,152,191,233,135,140,229,183, +180,229,183,180,231,164,190,228,188,154,228,184,187,228,185,137,230,147,141,228, +189,156,231,179,187,231,187,159,230,148,191,231,173,150,230,179,149,232,167,132, +105,110,102,111,114,109,97,99,105,195,179,110,104,101,114,114,97,109,105,101,110 +,116,97,115,101,108,101,99,116,114,195,179,110,105,99,111,100,101,115,99,114,105 +,112,99,105,195,179,110,99,108,97,115,105,102,105,99,97,100,111,115,99,111,110, +111,99,105,109,105,101,110,116,111,112,117,98,108,105,99,97,99,105,195,179,110, +114,101,108,97,99,105,111,110,97,100,97,115,105,110,102,111,114,109,195,161,116, +105,99,97,114,101,108,97,99,105,111,110,97,100,111,115,100,101,112,97,114,116,97 +,109,101,110,116,111,116,114,97,98,97,106,97,100,111,114,101,115,100,105,114,101 +,99,116,97,109,101,110,116,101,97,121,117,110,116,97,109,105,101,110,116,111,109 +,101,114,99,97,100,111,76,105,98,114,101,99,111,110,116,195,161,99,116,101,110, +111,115,104,97,98,105,116,97,99,105,111,110,101,115,99,117,109,112,108,105,109, +105,101,110,116,111,114,101,115,116,97,117,114,97,110,116,101,115,100,105,115, +112,111,115,105,99,105,195,179,110,99,111,110,115,101,99,117,101,110,99,105,97, +101,108,101,99,116,114,195,179,110,105,99,97,97,112,108,105,99,97,99,105,111,110 +,101,115,100,101,115,99,111,110,101,99,116,97,100,111,105,110,115,116,97,108,97, +99,105,195,179,110,114,101,97,108,105,122,97,99,105,195,179,110,117,116,105,108, +105,122,97,99,105,195,179,110,101,110,99,105,99,108,111,112,101,100,105,97,101, +110,102,101,114,109,101,100,97,100,101,115,105,110,115,116,114,117,109,101,110, +116,111,115,101,120,112,101,114,105,101,110,99,105,97,115,105,110,115,116,105, +116,117,99,105,195,179,110,112,97,114,116,105,99,117,108,97,114,101,115,115,117, +98,99,97,116,101,103,111,114,105,97,209,130,208,190,208,187,209,140,208,186,208, +190,208,160,208,190,209,129,209,129,208,184,208,184,209,128,208,176,208,177,208, +190,209,130,209,139,208,177,208,190,208,187,209,140,209,136,208,181,208,191,209, +128,208,190,209,129,209,130,208,190,208,188,208,190,208,182,208,181,209,130,208, +181,208,180,209,128,209,131,208,179,208,184,209,133,209,129,208,187,209,131,209, +135,208,176,208,181,209,129,208,181,208,185,209,135,208,176,209,129,208,178,209, +129,208,181,208,179,208,180,208,176,208,160,208,190,209,129,209,129,208,184,209, +143,208,156,208,190,209,129,208,186,208,178,208,181,208,180,209,128,209,131,208, +179,208,184,208,181,208,179,208,190,209,128,208,190,208,180,208,176,208,178,208, +190,208,191,209,128,208,190,209,129,208,180,208,176,208,189,208,189,209,139,209, +133,208,180,208,190,208,187,208,182,208,189,209,139,208,184,208,188,208,181,208, +189,208,189,208,190,208,156,208,190,209,129,208,186,208,178,209,139,209,128,209, +131,208,177,208,187,208,181,208,185,208,156,208,190,209,129,208,186,208,178,208, +176,209,129,209,130,209,128,208,176,208,189,209,139,208,189,208,184,209,135,208, +181,208,179,208,190,209,128,208,176,208,177,208,190,209,130,208,181,208,180,208, +190,208,187,208,182,208,181,208,189,209,131,209,129,208,187,209,131,208,179,208, +184,209,130,208,181,208,191,208,181,209,128,209,140,208,158,208,180,208,189,208, +176,208,186,208,190,208,191,208,190,209,130,208,190,208,188,209,131,209,128,208, +176,208,177,208,190,209,130,209,131,208,176,208,191,209,128,208,181,208,187,209, +143,208,178,208,190,208,190,208,177,209,137,208,181,208,190,208,180,208,189,208, +190,208,179,208,190,209,129,208,178,208,190,208,181,208,179,208,190,209,129,209, +130,208,176,209,130,209,140,208,184,208,180,209,128,209,131,208,179,208,190,208, +185,209,132,208,190,209,128,209,131,208,188,208,181,209,133,208,190,209,128,208, +190,209,136,208,190,208,191,209,128,208,190,209,130,208,184,208,178,209,129,209, +129,209,139,208,187,208,186,208,176,208,186,208,176,208,182,208,180,209,139,208, +185,208,178,208,187,208,176,209,129,209,130,208,184,208,179,209,128,209,131,208, +191,208,191,209,139,208,178,208,188,208,181,209,129,209,130,208,181,209,128,208, +176,208,177,208,190,209,130,208,176,209,129,208,186,208,176,208,183,208,176,208, +187,208,191,208,181,209,128,208,178,209,139,208,185,208,180,208,181,208,187,208, +176,209,130,209,140,208,180,208,181,208,189,209,140,208,179,208,184,208,191,208, +181,209,128,208,184,208,190,208,180,208,177,208,184,208,183,208,189,208,181,209, +129,208,190,209,129,208,189,208,190,208,178,208,181,208,188,208,190,208,188,208, +181,208,189,209,130,208,186,209,131,208,191,208,184,209,130,209,140,208,180,208, +190,208,187,208,182,208,189,208,176,209,128,208,176,208,188,208,186,208,176,209, +133,208,189,208,176,209,135,208,176,208,187,208,190,208,160,208,176,208,177,208, +190,209,130,208,176,208,162,208,190,208,187,209,140,208,186,208,190,209,129,208, +190,208,178,209,129,208,181,208,188,208,178,209,130,208,190,209,128,208,190,208, +185,208,189,208,176,209,135,208,176,208,187,208,176,209,129,208,191,208,184,209, +129,208,190,208,186,209,129,208,187,209,131,208,182,208,177,209,139,209,129,208, +184,209,129,209,130,208,181,208,188,208,191,208,181,209,135,208,176,209,130,208, +184,208,189,208,190,208,178,208,190,208,179,208,190,208,191,208,190,208,188,208, +190,209,137,208,184,209,129,208,176,208,185,209,130,208,190,208,178,208,191,208, +190,209,135,208,181,208,188,209,131,208,191,208,190,208,188,208,190,209,137,209, +140,208,180,208,190,208,187,208,182,208,189,208,190,209,129,209,129,209,139,208, +187,208,186,208,184,208,177,209,139,209,129,209,130,209,128,208,190,208,180,208, +176,208,189,208,189,209,139,208,181,208,188,208,189,208,190,208,179,208,184,208, +181,208,191,209,128,208,190,208,181,208,186,209,130,208,161,208,181,208,185,209, +135,208,176,209,129,208,188,208,190,208,180,208,181,208,187,208,184,209,130,208, +176,208,186,208,190,208,179,208,190,208,190,208,189,208,187,208,176,208,185,208, +189,208,179,208,190,209,128,208,190,208,180,208,181,208,178,208,181,209,128,209, +129,208,184,209,143,209,129,209,130,209,128,208,176,208,189,208,181,209,132,208, +184,208,187,209,140,208,188,209,139,209,131,209,128,208,190,208,178,208,189,209, +143,209,128,208,176,208,183,208,189,209,139,209,133,208,184,209,129,208,186,208, +176,209,130,209,140,208,189,208,181,208,180,208,181,208,187,209,142,209,143,208, +189,208,178,208,176,209,128,209,143,208,188,208,181,208,189,209,140,209,136,208, +181,208,188,208,189,208,190,208,179,208,184,209,133,208,180,208,176,208,189,208, +189,208,190,208,185,208,183,208,189,208,176,209,135,208,184,209,130,208,189,208, +181,208,187,209,140,208,183,209,143,209,132,208,190,209,128,209,131,208,188,208, +176,208,162,208,181,208,191,208,181,209,128,209,140,208,188,208,181,209,129,209, +143,209,134,208,176,208,183,208,176,209,137,208,184,209,130,209,139,208,155,209, +131,209,135,209,136,208,184,208,181,224,164,168,224,164,185,224,165,128,224,164, +130,224,164,149,224,164,176,224,164,168,224,165,135,224,164,133,224,164,170,224, +164,168,224,165,135,224,164,149,224,164,191,224,164,175,224,164,190,224,164,149, +224,164,176,224,165,135,224,164,130,224,164,133,224,164,168,224,165,141,224,164, +175,224,164,149,224,165,141,224,164,175,224,164,190,224,164,151,224,164,190,224, +164,135,224,164,161,224,164,172,224,164,190,224,164,176,224,165,135,224,164,149, +224,164,191,224,164,184,224,165,128,224,164,166,224,164,191,224,164,175,224,164, +190,224,164,170,224,164,185,224,164,178,224,165,135,224,164,184,224,164,191,224, +164,130,224,164,185,224,164,173,224,164,190,224,164,176,224,164,164,224,164,133, +224,164,170,224,164,168,224,165,128,224,164,181,224,164,190,224,164,178,224,165, +135,224,164,184,224,165,135,224,164,181,224,164,190,224,164,149,224,164,176,224, +164,164,224,165,135,224,164,174,224,165,135,224,164,176,224,165,135,224,164,185, +224,165,139,224,164,168,224,165,135,224,164,184,224,164,149,224,164,164,224,165, +135,224,164,172,224,164,185,224,165,129,224,164,164,224,164,184,224,164,190,224, +164,135,224,164,159,224,164,185,224,165,139,224,164,151,224,164,190,224,164,156, +224,164,190,224,164,168,224,165,135,224,164,174,224,164,191,224,164,168,224,164, +159,224,164,149,224,164,176,224,164,164,224,164,190,224,164,149,224,164,176,224, +164,168,224,164,190,224,164,137,224,164,168,224,164,149,224,165,135,224,164,175, +224,164,185,224,164,190,224,164,129,224,164,184,224,164,172,224,164,184,224,165, +135,224,164,173,224,164,190,224,164,183,224,164,190,224,164,134,224,164,170,224, +164,149,224,165,135,224,164,178,224,164,191,224,164,175,224,165,135,224,164,182, +224,165,129,224,164,176,224,165,130,224,164,135,224,164,184,224,164,149,224,165, +135,224,164,152,224,164,130,224,164,159,224,165,135,224,164,174,224,165,135,224, +164,176,224,165,128,224,164,184,224,164,149,224,164,164,224,164,190,224,164,174, +224,165,135,224,164,176,224,164,190,224,164,178,224,165,135,224,164,149,224,164, +176,224,164,133,224,164,167,224,164,191,224,164,149,224,164,133,224,164,170,224, +164,168,224,164,190,224,164,184,224,164,174,224,164,190,224,164,156,224,164,174, +224,165,129,224,164,157,224,165,135,224,164,149,224,164,190,224,164,176,224,164, +163,224,164,185,224,165,139,224,164,164,224,164,190,224,164,149,224,164,161,224, +164,188,224,165,128,224,164,175,224,164,185,224,164,190,224,164,130,224,164,185, +224,165,139,224,164,159,224,164,178,224,164,182,224,164,172,224,165,141,224,164, +166,224,164,178,224,164,191,224,164,175,224,164,190,224,164,156,224,165,128,224, +164,181,224,164,168,224,164,156,224,164,190,224,164,164,224,164,190,224,164,149, +224,165,136,224,164,184,224,165,135,224,164,134,224,164,170,224,164,149,224,164, +190,224,164,181,224,164,190,224,164,178,224,165,128,224,164,166,224,165,135,224, +164,168,224,165,135,224,164,170,224,165,130,224,164,176,224,165,128,224,164,170, +224,164,190,224,164,168,224,165,128,224,164,137,224,164,184,224,164,149,224,165, +135,224,164,185,224,165,139,224,164,151,224,165,128,224,164,172,224,165,136,224, +164,160,224,164,149,224,164,134,224,164,170,224,164,149,224,165,128,224,164,181, +224,164,176,224,165,141,224,164,183,224,164,151,224,164,190,224,164,130,224,164, +181,224,164,134,224,164,170,224,164,149,224,165,139,224,164,156,224,164,191,224, +164,178,224,164,190,224,164,156,224,164,190,224,164,168,224,164,190,224,164,184, +224,164,185,224,164,174,224,164,164,224,164,185,224,164,174,224,165,135,224,164, +130,224,164,137,224,164,168,224,164,149,224,165,128,224,164,175,224,164,190,224, +164,185,224,165,130,224,164,166,224,164,176,224,165,141,224,164,156,224,164,184, +224,165,130,224,164,154,224,165,128,224,164,170,224,164,184,224,164,130,224,164, +166,224,164,184,224,164,181,224,164,190,224,164,178,224,164,185,224,165,139,224, +164,168,224,164,190,224,164,185,224,165,139,224,164,164,224,165,128,224,164,156, +224,165,136,224,164,184,224,165,135,224,164,181,224,164,190,224,164,170,224,164, +184,224,164,156,224,164,168,224,164,164,224,164,190,224,164,168,224,165,135,224, +164,164,224,164,190,224,164,156,224,164,190,224,164,176,224,165,128,224,164,152, +224,164,190,224,164,175,224,164,178,224,164,156,224,164,191,224,164,178,224,165, +135,224,164,168,224,165,128,224,164,154,224,165,135,224,164,156,224,164,190,224, +164,130,224,164,154,224,164,170,224,164,164,224,165,141,224,164,176,224,164,151, +224,165,130,224,164,151,224,164,178,224,164,156,224,164,190,224,164,164,224,165, +135,224,164,172,224,164,190,224,164,185,224,164,176,224,164,134,224,164,170,224, +164,168,224,165,135,224,164,181,224,164,190,224,164,185,224,164,168,224,164,135, +224,164,184,224,164,149,224,164,190,224,164,184,224,165,129,224,164,172,224,164, +185,224,164,176,224,164,185,224,164,168,224,165,135,224,164,135,224,164,184,224, +164,184,224,165,135,224,164,184,224,164,185,224,164,191,224,164,164,224,164,172, +224,164,161,224,164,188,224,165,135,224,164,152,224,164,159,224,164,168,224,164, +190,224,164,164,224,164,178,224,164,190,224,164,182,224,164,170,224,164,190,224, +164,130,224,164,154,224,164,182,224,165,141,224,164,176,224,165,128,224,164,172, +224,164,161,224,164,188,224,165,128,224,164,185,224,165,139,224,164,164,224,165, +135,224,164,184,224,164,190,224,164,136,224,164,159,224,164,182,224,164,190,224, +164,175,224,164,166,224,164,184,224,164,149,224,164,164,224,165,128,224,164,156, +224,164,190,224,164,164,224,165,128,224,164,181,224,164,190,224,164,178,224,164, +190,224,164,185,224,164,156,224,164,190,224,164,176,224,164,170,224,164,159,224, +164,168,224,164,190,224,164,176,224,164,150,224,164,168,224,165,135,224,164,184, +224,164,161,224,164,188,224,164,149,224,164,174,224,164,191,224,164,178,224,164, +190,224,164,137,224,164,184,224,164,149,224,165,128,224,164,149,224,165,135,224, +164,181,224,164,178,224,164,178,224,164,151,224,164,164,224,164,190,224,164,150, +224,164,190,224,164,168,224,164,190,224,164,133,224,164,176,224,165,141,224,164, +165,224,164,156,224,164,185,224,164,190,224,164,130,224,164,166,224,165,135,224, +164,150,224,164,190,224,164,170,224,164,185,224,164,178,224,165,128,224,164,168, +224,164,191,224,164,175,224,164,174,224,164,172,224,164,191,224,164,168,224,164, +190,224,164,172,224,165,136,224,164,130,224,164,149,224,164,149,224,164,185,224, +165,128,224,164,130,224,164,149,224,164,185,224,164,168,224,164,190,224,164,166, +224,165,135,224,164,164,224,164,190,224,164,185,224,164,174,224,164,178,224,165, +135,224,164,149,224,164,190,224,164,171,224,165,128,224,164,156,224,164,172,224, +164,149,224,164,191,224,164,164,224,165,129,224,164,176,224,164,164,224,164,174, +224,164,190,224,164,130,224,164,151,224,164,181,224,164,185,224,165,128,224,164, +130,224,164,176,224,165,139,224,164,156,224,164,188,224,164,174,224,164,191,224, +164,178,224,165,128,224,164,134,224,164,176,224,165,139,224,164,170,224,164,184, +224,165,135,224,164,168,224,164,190,224,164,175,224,164,190,224,164,166,224,164, +181,224,164,178,224,165,135,224,164,168,224,165,135,224,164,150,224,164,190,224, +164,164,224,164,190,224,164,149,224,164,176,224,165,128,224,164,172,224,164,137, +224,164,168,224,164,149,224,164,190,224,164,156,224,164,181,224,164,190,224,164, +172,224,164,170,224,165,130,224,164,176,224,164,190,224,164,172,224,164,161,224, +164,188,224,164,190,224,164,184,224,165,140,224,164,166,224,164,190,224,164,182, +224,165,135,224,164,175,224,164,176,224,164,149,224,164,191,224,164,175,224,165, +135,224,164,149,224,164,185,224,164,190,224,164,130,224,164,133,224,164,149,224, +164,184,224,164,176,224,164,172,224,164,168,224,164,190,224,164,143,224,164,181, +224,164,185,224,164,190,224,164,130,224,164,184,224,165,141,224,164,165,224,164, +178,224,164,174,224,164,191,224,164,178,224,165,135,224,164,178,224,165,135,224, +164,150,224,164,149,224,164,181,224,164,191,224,164,183,224,164,175,224,164,149, +224,165,141,224,164,176,224,164,130,224,164,184,224,164,174,224,165,130,224,164, +185,224,164,165,224,164,190,224,164,168,224,164,190,216,170,216,179,216,170,216, +183,217,138,216,185,217,133,216,180,216,167,216,177,217,131,216,169,216,168,217, +136,216,167,216,179,216,183,216,169,216,167,217,132,216,181,217,129,216,173,216, +169,217,133,217,136,216,167,216,182,217,138,216,185,216,167,217,132,216,174,216, +167,216,181,216,169,216,167,217,132,217,133,216,178,217,138,216,175,216,167,217, +132,216,185,216,167,217,133,216,169,216,167,217,132,217,131,216,167,216,170,216, +168,216,167,217,132,216,177,216,175,217,136,216,175,216,168,216,177,217,134,216, +167,217,133,216,172,216,167,217,132,216,175,217,136,217,132,216,169,216,167,217, +132,216,185,216,167,217,132,217,133,216,167,217,132,217,133,217,136,217,130,216, +185,216,167,217,132,216,185,216,177,216,168,217,138,216,167,217,132,216,179,216, +177,217,138,216,185,216,167,217,132,216,172,217,136,216,167,217,132,216,167,217, +132,216,176,217,135,216,167,216,168,216,167,217,132,216,173,217,138,216,167,216, +169,216,167,217,132,216,173,217,130,217,136,217,130,216,167,217,132,217,131,216, +177,217,138,217,133,216,167,217,132,216,185,216,177,216,167,217,130,217,133,216, +173,217,129,217,136,216,184,216,169,216,167,217,132,216,171,216,167,217,134,217, +138,217,133,216,180,216,167,217,135,216,175,216,169,216,167,217,132,217,133,216, +177,216,163,216,169,216,167,217,132,217,130,216,177,216,162,217,134,216,167,217, +132,216,180,216,168,216,167,216,168,216,167,217,132,216,173,217,136,216,167,216, +177,216,167,217,132,216,172,216,175,217,138,216,175,216,167,217,132,216,163,216, +179,216,177,216,169,216,167,217,132,216,185,217,132,217,136,217,133,217,133,216, +172,217,133,217,136,216,185,216,169,216,167,217,132,216,177,216,173,217,133,217, +134,216,167,217,132,217,134,217,130,216,167,216,183,217,129,217,132,216,179,216, +183,217,138,217,134,216,167,217,132,217,131,217,136,217,138,216,170,216,167,217, +132,216,175,217,134,217,138,216,167,216,168,216,177,217,131,216,167,216,170,217, +135,216,167,217,132,216,177,217,138,216,167,216,182,216,170,216,173,217,138,216, +167,216,170,217,138,216,168,216,170,217,136,217,130,217,138,216,170,216,167,217, +132,216,163,217,136,217,132,217,137,216,167,217,132,216,168,216,177,217,138,216, +175,216,167,217,132,217,131,217,132,216,167,217,133,216,167,217,132,216,177,216, +167,216,168,216,183,216,167,217,132,216,180,216,174,216,181,217,138,216,179,217, +138,216,167,216,177,216,167,216,170,216,167,217,132,216,171,216,167,217,132,216, +171,216,167,217,132,216,181,217,132,216,167,216,169,216,167,217,132,216,173,216, +175,217,138,216,171,216,167,217,132,216,178,217,136,216,167,216,177,216,167,217, +132,216,174,217,132,217,138,216,172,216,167,217,132,216,172,217,133,217,138,216, +185,216,167,217,132,216,185,216,167,217,133,217,135,216,167,217,132,216,172,217, +133,216,167,217,132,216,167,217,132,216,179,216,167,216,185,216,169,217,133,216, +180,216,167,217,135,216,175,217,135,216,167,217,132,216,177,216,166,217,138,216, +179,216,167,217,132,216,175,216,174,217,136,217,132,216,167,217,132,217,129,217, +134,217,138,216,169,216,167,217,132,217,131,216,170,216,167,216,168,216,167,217, +132,216,175,217,136,216,177,217,138,216,167,217,132,216,175,216,177,217,136,216, +179,216,167,216,179,216,170,216,186,216,177,217,130,216,170,216,181,216,167,217, +133,217,138,217,133,216,167,217,132,216,168,217,134,216,167,216,170,216,167,217, +132,216,185,216,184,217,138,217,133,101,110,116,101,114,116,97,105,110,109,101, +110,116,117,110,100,101,114,115,116,97,110,100,105,110,103,32,61,32,102,117,110, +99,116,105,111,110,40,41,46,106,112,103,34,32,119,105,100,116,104,61,34,99,111, +110,102,105,103,117,114,97,116,105,111,110,46,112,110,103,34,32,119,105,100,116, +104,61,34,60,98,111,100,121,32,99,108,97,115,115,61,34,77,97,116,104,46,114,97, +110,100,111,109,40,41,99,111,110,116,101,109,112,111,114,97,114,121,32,85,110, +105,116,101,100,32,83,116,97,116,101,115,99,105,114,99,117,109,115,116,97,110,99 +,101,115,46,97,112,112,101,110,100,67,104,105,108,100,40,111,114,103,97,110,105, +122,97,116,105,111,110,115,60,115,112,97,110,32,99,108,97,115,115,61,34,34,62,60 +,105,109,103,32,115,114,99,61,34,47,100,105,115,116,105,110,103,117,105,115,104, +101,100,116,104,111,117,115,97,110,100,115,32,111,102,32,99,111,109,109,117,110, +105,99,97,116,105,111,110,99,108,101,97,114,34,62,60,47,100,105,118,62,105,110, +118,101,115,116,105,103,97,116,105,111,110,102,97,118,105,99,111,110,46,105,99, +111,34,32,109,97,114,103,105,110,45,114,105,103,104,116,58,98,97,115,101,100,32, +111,110,32,116,104,101,32,77,97,115,115,97,99,104,117,115,101,116,116,115,116,97 +,98,108,101,32,98,111,114,100,101,114,61,105,110,116,101,114,110,97,116,105,111, +110,97,108,97,108,115,111,32,107,110,111,119,110,32,97,115,112,114,111,110,117, +110,99,105,97,116,105,111,110,98,97,99,107,103,114,111,117,110,100,58,35,102,112 +,97,100,100,105,110,103,45,108,101,102,116,58,70,111,114,32,101,120,97,109,112, +108,101,44,32,109,105,115,99,101,108,108,97,110,101,111,117,115,38,108,116,59,47 +,109,97,116,104,38,103,116,59,112,115,121,99,104,111,108,111,103,105,99,97,108, +105,110,32,112,97,114,116,105,99,117,108,97,114,101,97,114,99,104,34,32,116,121, +112,101,61,34,102,111,114,109,32,109,101,116,104,111,100,61,34,97,115,32,111,112 +,112,111,115,101,100,32,116,111,83,117,112,114,101,109,101,32,67,111,117,114,116 +,111,99,99,97,115,105,111,110,97,108,108,121,32,65,100,100,105,116,105,111,110, +97,108,108,121,44,78,111,114,116,104,32,65,109,101,114,105,99,97,112,120,59,98, +97,99,107,103,114,111,117,110,100,111,112,112,111,114,116,117,110,105,116,105, +101,115,69,110,116,101,114,116,97,105,110,109,101,110,116,46,116,111,76,111,119, +101,114,67,97,115,101,40,109,97,110,117,102,97,99,116,117,114,105,110,103,112, +114,111,102,101,115,115,105,111,110,97,108,32,99,111,109,98,105,110,101,100,32, +119,105,116,104,70,111,114,32,105,110,115,116,97,110,99,101,44,99,111,110,115, +105,115,116,105,110,103,32,111,102,34,32,109,97,120,108,101,110,103,116,104,61, +34,114,101,116,117,114,110,32,102,97,108,115,101,59,99,111,110,115,99,105,111, +117,115,110,101,115,115,77,101,100,105,116,101,114,114,97,110,101,97,110,101,120 +,116,114,97,111,114,100,105,110,97,114,121,97,115,115,97,115,115,105,110,97,116, +105,111,110,115,117,98,115,101,113,117,101,110,116,108,121,32,98,117,116,116,111 +,110,32,116,121,112,101,61,34,116,104,101,32,110,117,109,98,101,114,32,111,102, +116,104,101,32,111,114,105,103,105,110,97,108,32,99,111,109,112,114,101,104,101, +110,115,105,118,101,114,101,102,101,114,115,32,116,111,32,116,104,101,60,47,117, +108,62,10,60,47,100,105,118,62,10,112,104,105,108,111,115,111,112,104,105,99,97, +108,108,111,99,97,116,105,111,110,46,104,114,101,102,119,97,115,32,112,117,98, +108,105,115,104,101,100,83,97,110,32,70,114,97,110,99,105,115,99,111,40,102,117, +110,99,116,105,111,110,40,41,123,10,60,100,105,118,32,105,100,61,34,109,97,105, +110,115,111,112,104,105,115,116,105,99,97,116,101,100,109,97,116,104,101,109,97, +116,105,99,97,108,32,47,104,101,97,100,62,13,10,60,98,111,100,121,115,117,103, +103,101,115,116,115,32,116,104,97,116,100,111,99,117,109,101,110,116,97,116,105, +111,110,99,111,110,99,101,110,116,114,97,116,105,111,110,114,101,108,97,116,105, +111,110,115,104,105,112,115,109,97,121,32,104,97,118,101,32,98,101,101,110,40, +102,111,114,32,101,120,97,109,112,108,101,44,84,104,105,115,32,97,114,116,105,99 +,108,101,32,105,110,32,115,111,109,101,32,99,97,115,101,115,112,97,114,116,115, +32,111,102,32,116,104,101,32,100,101,102,105,110,105,116,105,111,110,32,111,102, +71,114,101,97,116,32,66,114,105,116,97,105,110,32,99,101,108,108,112,97,100,100, +105,110,103,61,101,113,117,105,118,97,108,101,110,116,32,116,111,112,108,97,99, +101,104,111,108,100,101,114,61,34,59,32,102,111,110,116,45,115,105,122,101,58,32 +,106,117,115,116,105,102,105,99,97,116,105,111,110,98,101,108,105,101,118,101, +100,32,116,104,97,116,115,117,102,102,101,114,101,100,32,102,114,111,109,97,116, +116,101,109,112,116,101,100,32,116,111,32,108,101,97,100,101,114,32,111,102,32, +116,104,101,99,114,105,112,116,34,32,115,114,99,61,34,47,40,102,117,110,99,116, +105,111,110,40,41,32,123,97,114,101,32,97,118,97,105,108,97,98,108,101,10,9,60, +108,105,110,107,32,114,101,108,61,34,32,115,114,99,61,39,104,116,116,112,58,47, +47,105,110,116,101,114,101,115,116,101,100,32,105,110,99,111,110,118,101,110,116 +,105,111,110,97,108,32,34,32,97,108,116,61,34,34,32,47,62,60,47,97,114,101,32, +103,101,110,101,114,97,108,108,121,104,97,115,32,97,108,115,111,32,98,101,101, +110,109,111,115,116,32,112,111,112,117,108,97,114,32,99,111,114,114,101,115,112, +111,110,100,105,110,103,99,114,101,100,105,116,101,100,32,119,105,116,104,116, +121,108,101,61,34,98,111,114,100,101,114,58,60,47,97,62,60,47,115,112,97,110,62, +60,47,46,103,105,102,34,32,119,105,100,116,104,61,34,60,105,102,114,97,109,101, +32,115,114,99,61,34,116,97,98,108,101,32,99,108,97,115,115,61,34,105,110,108,105 +,110,101,45,98,108,111,99,107,59,97,99,99,111,114,100,105,110,103,32,116,111,32, +116,111,103,101,116,104,101,114,32,119,105,116,104,97,112,112,114,111,120,105, +109,97,116,101,108,121,112,97,114,108,105,97,109,101,110,116,97,114,121,109,111, +114,101,32,97,110,100,32,109,111,114,101,100,105,115,112,108,97,121,58,110,111, +110,101,59,116,114,97,100,105,116,105,111,110,97,108,108,121,112,114,101,100,111 +,109,105,110,97,110,116,108,121,38,110,98,115,112,59,124,38,110,98,115,112,59,38 +,110,98,115,112,59,60,47,115,112,97,110,62,32,99,101,108,108,115,112,97,99,105, +110,103,61,60,105,110,112,117,116,32,110,97,109,101,61,34,111,114,34,32,99,111, +110,116,101,110,116,61,34,99,111,110,116,114,111,118,101,114,115,105,97,108,112, +114,111,112,101,114,116,121,61,34,111,103,58,47,120,45,115,104,111,99,107,119,97 +,118,101,45,100,101,109,111,110,115,116,114,97,116,105,111,110,115,117,114,114, +111,117,110,100,101,100,32,98,121,78,101,118,101,114,116,104,101,108,101,115,115 +,44,119,97,115,32,116,104,101,32,102,105,114,115,116,99,111,110,115,105,100,101, +114,97,98,108,101,32,65,108,116,104,111,117,103,104,32,116,104,101,32,99,111,108 +,108,97,98,111,114,97,116,105,111,110,115,104,111,117,108,100,32,110,111,116,32, +98,101,112,114,111,112,111,114,116,105,111,110,32,111,102,60,115,112,97,110,32, +115,116,121,108,101,61,34,107,110,111,119,110,32,97,115,32,116,104,101,32,115, +104,111,114,116,108,121,32,97,102,116,101,114,102,111,114,32,105,110,115,116,97, +110,99,101,44,100,101,115,99,114,105,98,101,100,32,97,115,32,47,104,101,97,100, +62,10,60,98,111,100,121,32,115,116,97,114,116,105,110,103,32,119,105,116,104,105 +,110,99,114,101,97,115,105,110,103,108,121,32,116,104,101,32,102,97,99,116,32, +116,104,97,116,100,105,115,99,117,115,115,105,111,110,32,111,102,109,105,100,100 +,108,101,32,111,102,32,116,104,101,97,110,32,105,110,100,105,118,105,100,117,97, +108,100,105,102,102,105,99,117,108,116,32,116,111,32,112,111,105,110,116,32,111, +102,32,118,105,101,119,104,111,109,111,115,101,120,117,97,108,105,116,121,97,99, +99,101,112,116,97,110,99,101,32,111,102,60,47,115,112,97,110,62,60,47,100,105, +118,62,109,97,110,117,102,97,99,116,117,114,101,114,115,111,114,105,103,105,110, +32,111,102,32,116,104,101,99,111,109,109,111,110,108,121,32,117,115,101,100,105, +109,112,111,114,116,97,110,99,101,32,111,102,100,101,110,111,109,105,110,97,116, +105,111,110,115,98,97,99,107,103,114,111,117,110,100,58,32,35,108,101,110,103, +116,104,32,111,102,32,116,104,101,100,101,116,101,114,109,105,110,97,116,105,111 +,110,97,32,115,105,103,110,105,102,105,99,97,110,116,34,32,98,111,114,100,101, +114,61,34,48,34,62,114,101,118,111,108,117,116,105,111,110,97,114,121,112,114, +105,110,99,105,112,108,101,115,32,111,102,105,115,32,99,111,110,115,105,100,101, +114,101,100,119,97,115,32,100,101,118,101,108,111,112,101,100,73,110,100,111,45, +69,117,114,111,112,101,97,110,118,117,108,110,101,114,97,98,108,101,32,116,111, +112,114,111,112,111,110,101,110,116,115,32,111,102,97,114,101,32,115,111,109,101 +,116,105,109,101,115,99,108,111,115,101,114,32,116,111,32,116,104,101,78,101,119 +,32,89,111,114,107,32,67,105,116,121,32,110,97,109,101,61,34,115,101,97,114,99, +104,97,116,116,114,105,98,117,116,101,100,32,116,111,99,111,117,114,115,101,32, +111,102,32,116,104,101,109,97,116,104,101,109,97,116,105,99,105,97,110,98,121,32 +,116,104,101,32,101,110,100,32,111,102,97,116,32,116,104,101,32,101,110,100,32, +111,102,34,32,98,111,114,100,101,114,61,34,48,34,32,116,101,99,104,110,111,108, +111,103,105,99,97,108,46,114,101,109,111,118,101,67,108,97,115,115,40,98,114,97, +110,99,104,32,111,102,32,116,104,101,101,118,105,100,101,110,99,101,32,116,104, +97,116,33,91,101,110,100,105,102,93,45,45,62,13,10,73,110,115,116,105,116,117, +116,101,32,111,102,32,105,110,116,111,32,97,32,115,105,110,103,108,101,114,101, +115,112,101,99,116,105,118,101,108,121,46,97,110,100,32,116,104,101,114,101,102, +111,114,101,112,114,111,112,101,114,116,105,101,115,32,111,102,105,115,32,108, +111,99,97,116,101,100,32,105,110,115,111,109,101,32,111,102,32,119,104,105,99, +104,84,104,101,114,101,32,105,115,32,97,108,115,111,99,111,110,116,105,110,117, +101,100,32,116,111,32,97,112,112,101,97,114,97,110,99,101,32,111,102,32,38,97, +109,112,59,110,100,97,115,104,59,32,100,101,115,99,114,105,98,101,115,32,116,104 +,101,99,111,110,115,105,100,101,114,97,116,105,111,110,97,117,116,104,111,114,32 +,111,102,32,116,104,101,105,110,100,101,112,101,110,100,101,110,116,108,121,101, +113,117,105,112,112,101,100,32,119,105,116,104,100,111,101,115,32,110,111,116,32 +,104,97,118,101,60,47,97,62,60,97,32,104,114,101,102,61,34,99,111,110,102,117, +115,101,100,32,119,105,116,104,60,108,105,110,107,32,104,114,101,102,61,34,47,97 +,116,32,116,104,101,32,97,103,101,32,111,102,97,112,112,101,97,114,32,105,110,32 +,116,104,101,84,104,101,115,101,32,105,110,99,108,117,100,101,114,101,103,97,114 +,100,108,101,115,115,32,111,102,99,111,117,108,100,32,98,101,32,117,115,101,100, +32,115,116,121,108,101,61,38,113,117,111,116,59,115,101,118,101,114,97,108,32, +116,105,109,101,115,114,101,112,114,101,115,101,110,116,32,116,104,101,98,111, +100,121,62,10,60,47,104,116,109,108,62,116,104,111,117,103,104,116,32,116,111,32 +,98,101,112,111,112,117,108,97,116,105,111,110,32,111,102,112,111,115,115,105,98 +,105,108,105,116,105,101,115,112,101,114,99,101,110,116,97,103,101,32,111,102,97 +,99,99,101,115,115,32,116,111,32,116,104,101,97,110,32,97,116,116,101,109,112, +116,32,116,111,112,114,111,100,117,99,116,105,111,110,32,111,102,106,113,117,101 +,114,121,47,106,113,117,101,114,121,116,119,111,32,100,105,102,102,101,114,101, +110,116,98,101,108,111,110,103,32,116,111,32,116,104,101,101,115,116,97,98,108, +105,115,104,109,101,110,116,114,101,112,108,97,99,105,110,103,32,116,104,101,100 +,101,115,99,114,105,112,116,105,111,110,34,32,100,101,116,101,114,109,105,110, +101,32,116,104,101,97,118,97,105,108,97,98,108,101,32,102,111,114,65,99,99,111, +114,100,105,110,103,32,116,111,32,119,105,100,101,32,114,97,110,103,101,32,111, +102,9,60,100,105,118,32,99,108,97,115,115,61,34,109,111,114,101,32,99,111,109, +109,111,110,108,121,111,114,103,97,110,105,115,97,116,105,111,110,115,102,117, +110,99,116,105,111,110,97,108,105,116,121,119,97,115,32,99,111,109,112,108,101, +116,101,100,32,38,97,109,112,59,109,100,97,115,104,59,32,112,97,114,116,105,99, +105,112,97,116,105,111,110,116,104,101,32,99,104,97,114,97,99,116,101,114,97,110 +,32,97,100,100,105,116,105,111,110,97,108,97,112,112,101,97,114,115,32,116,111, +32,98,101,102,97,99,116,32,116,104,97,116,32,116,104,101,97,110,32,101,120,97, +109,112,108,101,32,111,102,115,105,103,110,105,102,105,99,97,110,116,108,121,111 +,110,109,111,117,115,101,111,118,101,114,61,34,98,101,99,97,117,115,101,32,116, +104,101,121,32,97,115,121,110,99,32,61,32,116,114,117,101,59,112,114,111,98,108, +101,109,115,32,119,105,116,104,115,101,101,109,115,32,116,111,32,104,97,118,101, +116,104,101,32,114,101,115,117,108,116,32,111,102,32,115,114,99,61,34,104,116, +116,112,58,47,47,102,97,109,105,108,105,97,114,32,119,105,116,104,112,111,115, +115,101,115,115,105,111,110,32,111,102,102,117,110,99,116,105,111,110,32,40,41, +32,123,116,111,111,107,32,112,108,97,99,101,32,105,110,97,110,100,32,115,111,109 +,101,116,105,109,101,115,115,117,98,115,116,97,110,116,105,97,108,108,121,60,115 +,112,97,110,62,60,47,115,112,97,110,62,105,115,32,111,102,116,101,110,32,117,115 +,101,100,105,110,32,97,110,32,97,116,116,101,109,112,116,103,114,101,97,116,32, +100,101,97,108,32,111,102,69,110,118,105,114,111,110,109,101,110,116,97,108,115, +117,99,99,101,115,115,102,117,108,108,121,32,118,105,114,116,117,97,108,108,121, +32,97,108,108,50,48,116,104,32,99,101,110,116,117,114,121,44,112,114,111,102,101 +,115,115,105,111,110,97,108,115,110,101,99,101,115,115,97,114,121,32,116,111,32, +100,101,116,101,114,109,105,110,101,100,32,98,121,99,111,109,112,97,116,105,98, +105,108,105,116,121,98,101,99,97,117,115,101,32,105,116,32,105,115,68,105,99,116 +,105,111,110,97,114,121,32,111,102,109,111,100,105,102,105,99,97,116,105,111,110 +,115,84,104,101,32,102,111,108,108,111,119,105,110,103,109,97,121,32,114,101,102 +,101,114,32,116,111,58,67,111,110,115,101,113,117,101,110,116,108,121,44,73,110, +116,101,114,110,97,116,105,111,110,97,108,97,108,116,104,111,117,103,104,32,115, +111,109,101,116,104,97,116,32,119,111,117,108,100,32,98,101,119,111,114,108,100, +39,115,32,102,105,114,115,116,99,108,97,115,115,105,102,105,101,100,32,97,115,98 +,111,116,116,111,109,32,111,102,32,116,104,101,40,112,97,114,116,105,99,117,108, +97,114,108,121,97,108,105,103,110,61,34,108,101,102,116,34,32,109,111,115,116,32 +,99,111,109,109,111,110,108,121,98,97,115,105,115,32,102,111,114,32,116,104,101, +102,111,117,110,100,97,116,105,111,110,32,111,102,99,111,110,116,114,105,98,117, +116,105,111,110,115,112,111,112,117,108,97,114,105,116,121,32,111,102,99,101,110 +,116,101,114,32,111,102,32,116,104,101,116,111,32,114,101,100,117,99,101,32,116, +104,101,106,117,114,105,115,100,105,99,116,105,111,110,115,97,112,112,114,111, +120,105,109,97,116,105,111,110,32,111,110,109,111,117,115,101,111,117,116,61,34, +78,101,119,32,84,101,115,116,97,109,101,110,116,99,111,108,108,101,99,116,105, +111,110,32,111,102,60,47,115,112,97,110,62,60,47,97,62,60,47,105,110,32,116,104, +101,32,85,110,105,116,101,100,102,105,108,109,32,100,105,114,101,99,116,111,114, +45,115,116,114,105,99,116,46,100,116,100,34,62,104,97,115,32,98,101,101,110,32, +117,115,101,100,114,101,116,117,114,110,32,116,111,32,116,104,101,97,108,116,104 +,111,117,103,104,32,116,104,105,115,99,104,97,110,103,101,32,105,110,32,116,104, +101,115,101,118,101,114,97,108,32,111,116,104,101,114,98,117,116,32,116,104,101, +114,101,32,97,114,101,117,110,112,114,101,99,101,100,101,110,116,101,100,105,115 +,32,115,105,109,105,108,97,114,32,116,111,101,115,112,101,99,105,97,108,108,121, +32,105,110,119,101,105,103,104,116,58,32,98,111,108,100,59,105,115,32,99,97,108, +108,101,100,32,116,104,101,99,111,109,112,117,116,97,116,105,111,110,97,108,105, +110,100,105,99,97,116,101,32,116,104,97,116,114,101,115,116,114,105,99,116,101, +100,32,116,111,9,60,109,101,116,97,32,110,97,109,101,61,34,97,114,101,32,116,121 +,112,105,99,97,108,108,121,99,111,110,102,108,105,99,116,32,119,105,116,104,72, +111,119,101,118,101,114,44,32,116,104,101,32,65,110,32,101,120,97,109,112,108, +101,32,111,102,99,111,109,112,97,114,101,100,32,119,105,116,104,113,117,97,110, +116,105,116,105,101,115,32,111,102,114,97,116,104,101,114,32,116,104,97,110,32, +97,99,111,110,115,116,101,108,108,97,116,105,111,110,110,101,99,101,115,115,97, +114,121,32,102,111,114,114,101,112,111,114,116,101,100,32,116,104,97,116,115,112 +,101,99,105,102,105,99,97,116,105,111,110,112,111,108,105,116,105,99,97,108,32, +97,110,100,38,110,98,115,112,59,38,110,98,115,112,59,60,114,101,102,101,114,101, +110,99,101,115,32,116,111,116,104,101,32,115,97,109,101,32,121,101,97,114,71,111 +,118,101,114,110,109,101,110,116,32,111,102,103,101,110,101,114,97,116,105,111, +110,32,111,102,104,97,118,101,32,110,111,116,32,98,101,101,110,115,101,118,101, +114,97,108,32,121,101,97,114,115,99,111,109,109,105,116,109,101,110,116,32,116, +111,9,9,60,117,108,32,99,108,97,115,115,61,34,118,105,115,117,97,108,105,122,97, +116,105,111,110,49,57,116,104,32,99,101,110,116,117,114,121,44,112,114,97,99,116 +,105,116,105,111,110,101,114,115,116,104,97,116,32,104,101,32,119,111,117,108, +100,97,110,100,32,99,111,110,116,105,110,117,101,100,111,99,99,117,112,97,116, +105,111,110,32,111,102,105,115,32,100,101,102,105,110,101,100,32,97,115,99,101, +110,116,114,101,32,111,102,32,116,104,101,116,104,101,32,97,109,111,117,110,116, +32,111,102,62,60,100,105,118,32,115,116,121,108,101,61,34,101,113,117,105,118,97 +,108,101,110,116,32,111,102,100,105,102,102,101,114,101,110,116,105,97,116,101, +98,114,111,117,103,104,116,32,97,98,111,117,116,109,97,114,103,105,110,45,108, +101,102,116,58,32,97,117,116,111,109,97,116,105,99,97,108,108,121,116,104,111, +117,103,104,116,32,111,102,32,97,115,83,111,109,101,32,111,102,32,116,104,101, +115,101,10,60,100,105,118,32,99,108,97,115,115,61,34,105,110,112,117,116,32,99, +108,97,115,115,61,34,114,101,112,108,97,99,101,100,32,119,105,116,104,105,115,32 +,111,110,101,32,111,102,32,116,104,101,101,100,117,99,97,116,105,111,110,32,97, +110,100,105,110,102,108,117,101,110,99,101,100,32,98,121,114,101,112,117,116,97, +116,105,111,110,32,97,115,10,60,109,101,116,97,32,110,97,109,101,61,34,97,99,99, +111,109,109,111,100,97,116,105,111,110,60,47,100,105,118,62,10,60,47,100,105,118 +,62,108,97,114,103,101,32,112,97,114,116,32,111,102,73,110,115,116,105,116,117, +116,101,32,102,111,114,116,104,101,32,115,111,45,99,97,108,108,101,100,32,97,103 +,97,105,110,115,116,32,116,104,101,32,73,110,32,116,104,105,115,32,99,97,115,101 +,44,119,97,115,32,97,112,112,111,105,110,116,101,100,99,108,97,105,109,101,100, +32,116,111,32,98,101,72,111,119,101,118,101,114,44,32,116,104,105,115,68,101,112 +,97,114,116,109,101,110,116,32,111,102,116,104,101,32,114,101,109,97,105,110,105 +,110,103,101,102,102,101,99,116,32,111,110,32,116,104,101,112,97,114,116,105,99, +117,108,97,114,108,121,32,100,101,97,108,32,119,105,116,104,32,116,104,101,10,60 +,100,105,118,32,115,116,121,108,101,61,34,97,108,109,111,115,116,32,97,108,119, +97,121,115,97,114,101,32,99,117,114,114,101,110,116,108,121,101,120,112,114,101, +115,115,105,111,110,32,111,102,112,104,105,108,111,115,111,112,104,121,32,111, +102,102,111,114,32,109,111,114,101,32,116,104,97,110,99,105,118,105,108,105,122, +97,116,105,111,110,115,111,110,32,116,104,101,32,105,115,108,97,110,100,115,101, +108,101,99,116,101,100,73,110,100,101,120,99,97,110,32,114,101,115,117,108,116, +32,105,110,34,32,118,97,108,117,101,61,34,34,32,47,62,116,104,101,32,115,116,114 +,117,99,116,117,114,101,32,47,62,60,47,97,62,60,47,100,105,118,62,77,97,110,121, +32,111,102,32,116,104,101,115,101,99,97,117,115,101,100,32,98,121,32,116,104,101 +,111,102,32,116,104,101,32,85,110,105,116,101,100,115,112,97,110,32,99,108,97, +115,115,61,34,109,99,97,110,32,98,101,32,116,114,97,99,101,100,105,115,32,114, +101,108,97,116,101,100,32,116,111,98,101,99,97,109,101,32,111,110,101,32,111,102 +,105,115,32,102,114,101,113,117,101,110,116,108,121,108,105,118,105,110,103,32, +105,110,32,116,104,101,116,104,101,111,114,101,116,105,99,97,108,108,121,70,111, +108,108,111,119,105,110,103,32,116,104,101,82,101,118,111,108,117,116,105,111, +110,97,114,121,103,111,118,101,114,110,109,101,110,116,32,105,110,105,115,32,100 +,101,116,101,114,109,105,110,101,100,116,104,101,32,112,111,108,105,116,105,99, +97,108,105,110,116,114,111,100,117,99,101,100,32,105,110,115,117,102,102,105,99, +105,101,110,116,32,116,111,100,101,115,99,114,105,112,116,105,111,110,34,62,115, +104,111,114,116,32,115,116,111,114,105,101,115,115,101,112,97,114,97,116,105,111 +,110,32,111,102,97,115,32,116,111,32,119,104,101,116,104,101,114,107,110,111,119 +,110,32,102,111,114,32,105,116,115,119,97,115,32,105,110,105,116,105,97,108,108, +121,100,105,115,112,108,97,121,58,98,108,111,99,107,105,115,32,97,110,32,101,120 +,97,109,112,108,101,116,104,101,32,112,114,105,110,99,105,112,97,108,99,111,110, +115,105,115,116,115,32,111,102,32,97,114,101,99,111,103,110,105,122,101,100,32, +97,115,47,98,111,100,121,62,60,47,104,116,109,108,62,97,32,115,117,98,115,116,97 +,110,116,105,97,108,114,101,99,111,110,115,116,114,117,99,116,101,100,104,101,97 +,100,32,111,102,32,115,116,97,116,101,114,101,115,105,115,116,97,110,99,101,32, +116,111,117,110,100,101,114,103,114,97,100,117,97,116,101,84,104,101,114,101,32, +97,114,101,32,116,119,111,103,114,97,118,105,116,97,116,105,111,110,97,108,97, +114,101,32,100,101,115,99,114,105,98,101,100,105,110,116,101,110,116,105,111,110 +,97,108,108,121,115,101,114,118,101,100,32,97,115,32,116,104,101,99,108,97,115, +115,61,34,104,101,97,100,101,114,111,112,112,111,115,105,116,105,111,110,32,116, +111,102,117,110,100,97,109,101,110,116,97,108,108,121,100,111,109,105,110,97,116 +,101,100,32,116,104,101,97,110,100,32,116,104,101,32,111,116,104,101,114,97,108, +108,105,97,110,99,101,32,119,105,116,104,119,97,115,32,102,111,114,99,101,100,32 +,116,111,114,101,115,112,101,99,116,105,118,101,108,121,44,97,110,100,32,112,111 +,108,105,116,105,99,97,108,105,110,32,115,117,112,112,111,114,116,32,111,102,112 +,101,111,112,108,101,32,105,110,32,116,104,101,50,48,116,104,32,99,101,110,116, +117,114,121,46,97,110,100,32,112,117,98,108,105,115,104,101,100,108,111,97,100, +67,104,97,114,116,98,101,97,116,116,111,32,117,110,100,101,114,115,116,97,110, +100,109,101,109,98,101,114,32,115,116,97,116,101,115,101,110,118,105,114,111,110 +,109,101,110,116,97,108,102,105,114,115,116,32,104,97,108,102,32,111,102,99,111, +117,110,116,114,105,101,115,32,97,110,100,97,114,99,104,105,116,101,99,116,117, +114,97,108,98,101,32,99,111,110,115,105,100,101,114,101,100,99,104,97,114,97,99, +116,101,114,105,122,101,100,99,108,101,97,114,73,110,116,101,114,118,97,108,97, +117,116,104,111,114,105,116,97,116,105,118,101,70,101,100,101,114,97,116,105,111 +,110,32,111,102,119,97,115,32,115,117,99,99,101,101,100,101,100,97,110,100,32, +116,104,101,114,101,32,97,114,101,97,32,99,111,110,115,101,113,117,101,110,99, +101,116,104,101,32,80,114,101,115,105,100,101,110,116,97,108,115,111,32,105,110, +99,108,117,100,101,100,102,114,101,101,32,115,111,102,116,119,97,114,101,115,117 +,99,99,101,115,115,105,111,110,32,111,102,100,101,118,101,108,111,112,101,100,32 +,116,104,101,119,97,115,32,100,101,115,116,114,111,121,101,100,97,119,97,121,32, +102,114,111,109,32,116,104,101,59,10,60,47,115,99,114,105,112,116,62,10,60,97, +108,116,104,111,117,103,104,32,116,104,101,121,102,111,108,108,111,119,101,100, +32,98,121,32,97,109,111,114,101,32,112,111,119,101,114,102,117,108,114,101,115, +117,108,116,101,100,32,105,110,32,97,85,110,105,118,101,114,115,105,116,121,32, +111,102,72,111,119,101,118,101,114,44,32,109,97,110,121,116,104,101,32,112,114, +101,115,105,100,101,110,116,72,111,119,101,118,101,114,44,32,115,111,109,101,105 +,115,32,116,104,111,117,103,104,116,32,116,111,117,110,116,105,108,32,116,104, +101,32,101,110,100,119,97,115,32,97,110,110,111,117,110,99,101,100,97,114,101,32 +,105,109,112,111,114,116,97,110,116,97,108,115,111,32,105,110,99,108,117,100,101 +,115,62,60,105,110,112,117,116,32,116,121,112,101,61,116,104,101,32,99,101,110, +116,101,114,32,111,102,32,68,79,32,78,79,84,32,65,76,84,69,82,117,115,101,100,32 +,116,111,32,114,101,102,101,114,116,104,101,109,101,115,47,63,115,111,114,116,61 +,116,104,97,116,32,104,97,100,32,98,101,101,110,116,104,101,32,98,97,115,105,115 +,32,102,111,114,104,97,115,32,100,101,118,101,108,111,112,101,100,105,110,32,116 +,104,101,32,115,117,109,109,101,114,99,111,109,112,97,114,97,116,105,118,101,108 +,121,100,101,115,99,114,105,98,101,100,32,116,104,101,115,117,99,104,32,97,115, +32,116,104,111,115,101,116,104,101,32,114,101,115,117,108,116,105,110,103,105, +115,32,105,109,112,111,115,115,105,98,108,101,118,97,114,105,111,117,115,32,111, +116,104,101,114,83,111,117,116,104,32,65,102,114,105,99,97,110,104,97,118,101,32 +,116,104,101,32,115,97,109,101,101,102,102,101,99,116,105,118,101,110,101,115, +115,105,110,32,119,104,105,99,104,32,99,97,115,101,59,32,116,101,120,116,45,97, +108,105,103,110,58,115,116,114,117,99,116,117,114,101,32,97,110,100,59,32,98,97, +99,107,103,114,111,117,110,100,58,114,101,103,97,114,100,105,110,103,32,116,104, +101,115,117,112,112,111,114,116,101,100,32,116,104,101,105,115,32,97,108,115,111 +,32,107,110,111,119,110,115,116,121,108,101,61,34,109,97,114,103,105,110,105,110 +,99,108,117,100,105,110,103,32,116,104,101,98,97,104,97,115,97,32,77,101,108,97, +121,117,110,111,114,115,107,32,98,111,107,109,195,165,108,110,111,114,115,107,32 +,110,121,110,111,114,115,107,115,108,111,118,101,110,197,161,196,141,105,110,97, +105,110,116,101,114,110,97,99,105,111,110,97,108,99,97,108,105,102,105,99,97,99, +105,195,179,110,99,111,109,117,110,105,99,97,99,105,195,179,110,99,111,110,115, +116,114,117,99,99,105,195,179,110,34,62,60,100,105,118,32,99,108,97,115,115,61, +34,100,105,115,97,109,98,105,103,117,97,116,105,111,110,68,111,109,97,105,110,78 +,97,109,101,39,44,32,39,97,100,109,105,110,105,115,116,114,97,116,105,111,110, +115,105,109,117,108,116,97,110,101,111,117,115,108,121,116,114,97,110,115,112, +111,114,116,97,116,105,111,110,73,110,116,101,114,110,97,116,105,111,110,97,108, +32,109,97,114,103,105,110,45,98,111,116,116,111,109,58,114,101,115,112,111,110, +115,105,98,105,108,105,116,121,60,33,91,101,110,100,105,102,93,45,45,62,10,60,47 +,62,60,109,101,116,97,32,110,97,109,101,61,34,105,109,112,108,101,109,101,110, +116,97,116,105,111,110,105,110,102,114,97,115,116,114,117,99,116,117,114,101,114 +,101,112,114,101,115,101,110,116,97,116,105,111,110,98,111,114,100,101,114,45,98 +,111,116,116,111,109,58,60,47,104,101,97,100,62,10,60,98,111,100,121,62,61,104, +116,116,112,37,51,65,37,50,70,37,50,70,60,102,111,114,109,32,109,101,116,104,111 +,100,61,34,109,101,116,104,111,100,61,34,112,111,115,116,34,32,47,102,97,118,105 +,99,111,110,46,105,99,111,34,32,125,41,59,10,60,47,115,99,114,105,112,116,62,10, +46,115,101,116,65,116,116,114,105,98,117,116,101,40,65,100,109,105,110,105,115, +116,114,97,116,105,111,110,61,32,110,101,119,32,65,114,114,97,121,40,41,59,60,33 +,91,101,110,100,105,102,93,45,45,62,13,10,100,105,115,112,108,97,121,58,98,108, +111,99,107,59,85,110,102,111,114,116,117,110,97,116,101,108,121,44,34,62,38,110, +98,115,112,59,60,47,100,105,118,62,47,102,97,118,105,99,111,110,46,105,99,111,34 +,62,61,39,115,116,121,108,101,115,104,101,101,116,39,32,105,100,101,110,116,105, +102,105,99,97,116,105,111,110,44,32,102,111,114,32,101,120,97,109,112,108,101,44 +,60,108,105,62,60,97,32,104,114,101,102,61,34,47,97,110,32,97,108,116,101,114, +110,97,116,105,118,101,97,115,32,97,32,114,101,115,117,108,116,32,111,102,112, +116,34,62,60,47,115,99,114,105,112,116,62,10,116,121,112,101,61,34,115,117,98, +109,105,116,34,32,10,40,102,117,110,99,116,105,111,110,40,41,32,123,114,101,99, +111,109,109,101,110,100,97,116,105,111,110,102,111,114,109,32,97,99,116,105,111, +110,61,34,47,116,114,97,110,115,102,111,114,109,97,116,105,111,110,114,101,99, +111,110,115,116,114,117,99,116,105,111,110,46,115,116,121,108,101,46,100,105,115 +,112,108,97,121,32,65,99,99,111,114,100,105,110,103,32,116,111,32,104,105,100, +100,101,110,34,32,110,97,109,101,61,34,97,108,111,110,103,32,119,105,116,104,32, +116,104,101,100,111,99,117,109,101,110,116,46,98,111,100,121,46,97,112,112,114, +111,120,105,109,97,116,101,108,121,32,67,111,109,109,117,110,105,99,97,116,105, +111,110,115,112,111,115,116,34,32,97,99,116,105,111,110,61,34,109,101,97,110,105 +,110,103,32,38,113,117,111,116,59,45,45,60,33,91,101,110,100,105,102,93,45,45,62 +,80,114,105,109,101,32,77,105,110,105,115,116,101,114,99,104,97,114,97,99,116, +101,114,105,115,116,105,99,60,47,97,62,32,60,97,32,99,108,97,115,115,61,116,104, +101,32,104,105,115,116,111,114,121,32,111,102,32,111,110,109,111,117,115,101,111 +,118,101,114,61,34,116,104,101,32,103,111,118,101,114,110,109,101,110,116,104, +114,101,102,61,34,104,116,116,112,115,58,47,47,119,97,115,32,111,114,105,103,105 +,110,97,108,108,121,119,97,115,32,105,110,116,114,111,100,117,99,101,100,99,108, +97,115,115,105,102,105,99,97,116,105,111,110,114,101,112,114,101,115,101,110,116 +,97,116,105,118,101,97,114,101,32,99,111,110,115,105,100,101,114,101,100,60,33, +91,101,110,100,105,102,93,45,45,62,10,10,100,101,112,101,110,100,115,32,111,110, +32,116,104,101,85,110,105,118,101,114,115,105,116,121,32,111,102,32,105,110,32, +99,111,110,116,114,97,115,116,32,116,111,32,112,108,97,99,101,104,111,108,100, +101,114,61,34,105,110,32,116,104,101,32,99,97,115,101,32,111,102,105,110,116,101 +,114,110,97,116,105,111,110,97,108,32,99,111,110,115,116,105,116,117,116,105,111 +,110,97,108,115,116,121,108,101,61,34,98,111,114,100,101,114,45,58,32,102,117, +110,99,116,105,111,110,40,41,32,123,66,101,99,97,117,115,101,32,111,102,32,116, +104,101,45,115,116,114,105,99,116,46,100,116,100,34,62,10,60,116,97,98,108,101, +32,99,108,97,115,115,61,34,97,99,99,111,109,112,97,110,105,101,100,32,98,121,97, +99,99,111,117,110,116,32,111,102,32,116,104,101,60,115,99,114,105,112,116,32,115 +,114,99,61,34,47,110,97,116,117,114,101,32,111,102,32,116,104,101,32,116,104,101 +,32,112,101,111,112,108,101,32,105,110,32,105,110,32,97,100,100,105,116,105,111, +110,32,116,111,115,41,59,32,106,115,46,105,100,32,61,32,105,100,34,32,119,105, +100,116,104,61,34,49,48,48,37,34,114,101,103,97,114,100,105,110,103,32,116,104, +101,32,82,111,109,97,110,32,67,97,116,104,111,108,105,99,97,110,32,105,110,100, +101,112,101,110,100,101,110,116,102,111,108,108,111,119,105,110,103,32,116,104, +101,32,46,103,105,102,34,32,119,105,100,116,104,61,34,49,116,104,101,32,102,111, +108,108,111,119,105,110,103,32,100,105,115,99,114,105,109,105,110,97,116,105,111 +,110,97,114,99,104,97,101,111,108,111,103,105,99,97,108,112,114,105,109,101,32, +109,105,110,105,115,116,101,114,46,106,115,34,62,60,47,115,99,114,105,112,116,62 +,99,111,109,98,105,110,97,116,105,111,110,32,111,102,32,109,97,114,103,105,110, +119,105,100,116,104,61,34,99,114,101,97,116,101,69,108,101,109,101,110,116,40, +119,46,97,116,116,97,99,104,69,118,101,110,116,40,60,47,97,62,60,47,116,100,62, +60,47,116,114,62,115,114,99,61,34,104,116,116,112,115,58,47,47,97,73,110,32,112, +97,114,116,105,99,117,108,97,114,44,32,97,108,105,103,110,61,34,108,101,102,116, +34,32,67,122,101,99,104,32,82,101,112,117,98,108,105,99,85,110,105,116,101,100, +32,75,105,110,103,100,111,109,99,111,114,114,101,115,112,111,110,100,101,110,99, +101,99,111,110,99,108,117,100,101,100,32,116,104,97,116,46,104,116,109,108,34,32 +,116,105,116,108,101,61,34,40,102,117,110,99,116,105,111,110,32,40,41,32,123,99, +111,109,101,115,32,102,114,111,109,32,116,104,101,97,112,112,108,105,99,97,116, +105,111,110,32,111,102,60,115,112,97,110,32,99,108,97,115,115,61,34,115,98,101, +108,105,101,118,101,100,32,116,111,32,98,101,101,109,101,110,116,40,39,115,99, +114,105,112,116,39,60,47,97,62,10,60,47,108,105,62,10,60,108,105,118,101,114,121 +,32,100,105,102,102,101,114,101,110,116,62,60,115,112,97,110,32,99,108,97,115, +115,61,34,111,112,116,105,111,110,32,118,97,108,117,101,61,34,40,97,108,115,111, +32,107,110,111,119,110,32,97,115,9,60,108,105,62,60,97,32,104,114,101,102,61,34, +62,60,105,110,112,117,116,32,110,97,109,101,61,34,115,101,112,97,114,97,116,101, +100,32,102,114,111,109,114,101,102,101,114,114,101,100,32,116,111,32,97,115,32, +118,97,108,105,103,110,61,34,116,111,112,34,62,102,111,117,110,100,101,114,32, +111,102,32,116,104,101,97,116,116,101,109,112,116,105,110,103,32,116,111,32,99, +97,114,98,111,110,32,100,105,111,120,105,100,101,10,10,60,100,105,118,32,99,108, +97,115,115,61,34,99,108,97,115,115,61,34,115,101,97,114,99,104,45,47,98,111,100, +121,62,10,60,47,104,116,109,108,62,111,112,112,111,114,116,117,110,105,116,121, +32,116,111,99,111,109,109,117,110,105,99,97,116,105,111,110,115,60,47,104,101,97 +,100,62,13,10,60,98,111,100,121,32,115,116,121,108,101,61,34,119,105,100,116,104 +,58,84,105,225,186,191,110,103,32,86,105,225,187,135,116,99,104,97,110,103,101, +115,32,105,110,32,116,104,101,98,111,114,100,101,114,45,99,111,108,111,114,58,35 +,48,34,32,98,111,114,100,101,114,61,34,48,34,32,60,47,115,112,97,110,62,60,47, +100,105,118,62,60,119,97,115,32,100,105,115,99,111,118,101,114,101,100,34,32,116 +,121,112,101,61,34,116,101,120,116,34,32,41,59,10,60,47,115,99,114,105,112,116, +62,10,10,68,101,112,97,114,116,109,101,110,116,32,111,102,32,101,99,99,108,101, +115,105,97,115,116,105,99,97,108,116,104,101,114,101,32,104,97,115,32,98,101,101 +,110,114,101,115,117,108,116,105,110,103,32,102,114,111,109,60,47,98,111,100,121 +,62,60,47,104,116,109,108,62,104,97,115,32,110,101,118,101,114,32,98,101,101,110 +,116,104,101,32,102,105,114,115,116,32,116,105,109,101,105,110,32,114,101,115, +112,111,110,115,101,32,116,111,97,117,116,111,109,97,116,105,99,97,108,108,121, +32,60,47,100,105,118,62,10,10,60,100,105,118,32,105,119,97,115,32,99,111,110,115 +,105,100,101,114,101,100,112,101,114,99,101,110,116,32,111,102,32,116,104,101,34 +,32,47,62,60,47,97,62,60,47,100,105,118,62,99,111,108,108,101,99,116,105,111,110 +,32,111,102,32,100,101,115,99,101,110,100,101,100,32,102,114,111,109,115,101,99, +116,105,111,110,32,111,102,32,116,104,101,97,99,99,101,112,116,45,99,104,97,114, +115,101,116,116,111,32,98,101,32,99,111,110,102,117,115,101,100,109,101,109,98, +101,114,32,111,102,32,116,104,101,32,112,97,100,100,105,110,103,45,114,105,103, +104,116,58,116,114,97,110,115,108,97,116,105,111,110,32,111,102,105,110,116,101, +114,112,114,101,116,97,116,105,111,110,32,104,114,101,102,61,39,104,116,116,112, +58,47,47,119,104,101,116,104,101,114,32,111,114,32,110,111,116,84,104,101,114, +101,32,97,114,101,32,97,108,115,111,116,104,101,114,101,32,97,114,101,32,109,97, +110,121,97,32,115,109,97,108,108,32,110,117,109,98,101,114,111,116,104,101,114, +32,112,97,114,116,115,32,111,102,105,109,112,111,115,115,105,98,108,101,32,116, +111,32,32,99,108,97,115,115,61,34,98,117,116,116,111,110,108,111,99,97,116,101, +100,32,105,110,32,116,104,101,46,32,72,111,119,101,118,101,114,44,32,116,104,101 +,97,110,100,32,101,118,101,110,116,117,97,108,108,121,65,116,32,116,104,101,32, +101,110,100,32,111,102,32,98,101,99,97,117,115,101,32,111,102,32,105,116,115,114 +,101,112,114,101,115,101,110,116,115,32,116,104,101,60,102,111,114,109,32,97,99, +116,105,111,110,61,34,32,109,101,116,104,111,100,61,34,112,111,115,116,34,105, +116,32,105,115,32,112,111,115,115,105,98,108,101,109,111,114,101,32,108,105,107, +101,108,121,32,116,111,97,110,32,105,110,99,114,101,97,115,101,32,105,110,104,97 +,118,101,32,97,108,115,111,32,98,101,101,110,99,111,114,114,101,115,112,111,110, +100,115,32,116,111,97,110,110,111,117,110,99,101,100,32,116,104,97,116,97,108, +105,103,110,61,34,114,105,103,104,116,34,62,109,97,110,121,32,99,111,117,110,116 +,114,105,101,115,102,111,114,32,109,97,110,121,32,121,101,97,114,115,101,97,114, +108,105,101,115,116,32,107,110,111,119,110,98,101,99,97,117,115,101,32,105,116, +32,119,97,115,112,116,34,62,60,47,115,99,114,105,112,116,62,13,32,118,97,108,105 +,103,110,61,34,116,111,112,34,32,105,110,104,97,98,105,116,97,110,116,115,32,111 +,102,102,111,108,108,111,119,105,110,103,32,121,101,97,114,13,10,60,100,105,118, +32,99,108,97,115,115,61,34,109,105,108,108,105,111,110,32,112,101,111,112,108, +101,99,111,110,116,114,111,118,101,114,115,105,97,108,32,99,111,110,99,101,114, +110,105,110,103,32,116,104,101,97,114,103,117,101,32,116,104,97,116,32,116,104, +101,103,111,118,101,114,110,109,101,110,116,32,97,110,100,97,32,114,101,102,101, +114,101,110,99,101,32,116,111,116,114,97,110,115,102,101,114,114,101,100,32,116, +111,100,101,115,99,114,105,98,105,110,103,32,116,104,101,32,115,116,121,108,101, +61,34,99,111,108,111,114,58,97,108,116,104,111,117,103,104,32,116,104,101,114, +101,98,101,115,116,32,107,110,111,119,110,32,102,111,114,115,117,98,109,105,116, +34,32,110,97,109,101,61,34,109,117,108,116,105,112,108,105,99,97,116,105,111,110 +,109,111,114,101,32,116,104,97,110,32,111,110,101,32,114,101,99,111,103,110,105, +116,105,111,110,32,111,102,67,111,117,110,99,105,108,32,111,102,32,116,104,101, +101,100,105,116,105,111,110,32,111,102,32,116,104,101,32,32,60,109,101,116,97,32 +,110,97,109,101,61,34,69,110,116,101,114,116,97,105,110,109,101,110,116,32,97, +119,97,121,32,102,114,111,109,32,116,104,101,32,59,109,97,114,103,105,110,45,114 +,105,103,104,116,58,97,116,32,116,104,101,32,116,105,109,101,32,111,102,105,110, +118,101,115,116,105,103,97,116,105,111,110,115,99,111,110,110,101,99,116,101,100 +,32,119,105,116,104,97,110,100,32,109,97,110,121,32,111,116,104,101,114,97,108, +116,104,111,117,103,104,32,105,116,32,105,115,98,101,103,105,110,110,105,110,103 +,32,119,105,116,104,32,60,115,112,97,110,32,99,108,97,115,115,61,34,100,101,115, +99,101,110,100,97,110,116,115,32,111,102,60,115,112,97,110,32,99,108,97,115,115, +61,34,105,32,97,108,105,103,110,61,34,114,105,103,104,116,34,60,47,104,101,97, +100,62,10,60,98,111,100,121,32,97,115,112,101,99,116,115,32,111,102,32,116,104, +101,104,97,115,32,115,105,110,99,101,32,98,101,101,110,69,117,114,111,112,101,97 +,110,32,85,110,105,111,110,114,101,109,105,110,105,115,99,101,110,116,32,111,102 +,109,111,114,101,32,100,105,102,102,105,99,117,108,116,86,105,99,101,32,80,114, +101,115,105,100,101,110,116,99,111,109,112,111,115,105,116,105,111,110,32,111, +102,112,97,115,115,101,100,32,116,104,114,111,117,103,104,109,111,114,101,32,105 +,109,112,111,114,116,97,110,116,102,111,110,116,45,115,105,122,101,58,49,49,112, +120,101,120,112,108,97,110,97,116,105,111,110,32,111,102,116,104,101,32,99,111, +110,99,101,112,116,32,111,102,119,114,105,116,116,101,110,32,105,110,32,116,104, +101,9,60,115,112,97,110,32,99,108,97,115,115,61,34,105,115,32,111,110,101,32,111 +,102,32,116,104,101,32,114,101,115,101,109,98,108,97,110,99,101,32,116,111,111, +110,32,116,104,101,32,103,114,111,117,110,100,115,119,104,105,99,104,32,99,111, +110,116,97,105,110,115,105,110,99,108,117,100,105,110,103,32,116,104,101,32,100, +101,102,105,110,101,100,32,98,121,32,116,104,101,112,117,98,108,105,99,97,116, +105,111,110,32,111,102,109,101,97,110,115,32,116,104,97,116,32,116,104,101,111, +117,116,115,105,100,101,32,111,102,32,116,104,101,115,117,112,112,111,114,116,32 +,111,102,32,116,104,101,60,105,110,112,117,116,32,99,108,97,115,115,61,34,60,115 +,112,97,110,32,99,108,97,115,115,61,34,116,40,77,97,116,104,46,114,97,110,100, +111,109,40,41,109,111,115,116,32,112,114,111,109,105,110,101,110,116,100,101,115 +,99,114,105,112,116,105,111,110,32,111,102,67,111,110,115,116,97,110,116,105,110 +,111,112,108,101,119,101,114,101,32,112,117,98,108,105,115,104,101,100,60,100, +105,118,32,99,108,97,115,115,61,34,115,101,97,112,112,101,97,114,115,32,105,110, +32,116,104,101,49,34,32,104,101,105,103,104,116,61,34,49,34,32,109,111,115,116, +32,105,109,112,111,114,116,97,110,116,119,104,105,99,104,32,105,110,99,108,117, +100,101,115,119,104,105,99,104,32,104,97,100,32,98,101,101,110,100,101,115,116, +114,117,99,116,105,111,110,32,111,102,116,104,101,32,112,111,112,117,108,97,116, +105,111,110,10,9,60,100,105,118,32,99,108,97,115,115,61,34,112,111,115,115,105, +98,105,108,105,116,121,32,111,102,115,111,109,101,116,105,109,101,115,32,117,115 +,101,100,97,112,112,101,97,114,32,116,111,32,104,97,118,101,115,117,99,99,101, +115,115,32,111,102,32,116,104,101,105,110,116,101,110,100,101,100,32,116,111,32, +98,101,112,114,101,115,101,110,116,32,105,110,32,116,104,101,115,116,121,108,101 +,61,34,99,108,101,97,114,58,98,13,10,60,47,115,99,114,105,112,116,62,13,10,60, +119,97,115,32,102,111,117,110,100,101,100,32,105,110,105,110,116,101,114,118,105 +,101,119,32,119,105,116,104,95,105,100,34,32,99,111,110,116,101,110,116,61,34,99 +,97,112,105,116,97,108,32,111,102,32,116,104,101,13,10,60,108,105,110,107,32,114 +,101,108,61,34,115,114,101,108,101,97,115,101,32,111,102,32,116,104,101,112,111, +105,110,116,32,111,117,116,32,116,104,97,116,120,77,76,72,116,116,112,82,101,113 +,117,101,115,116,97,110,100,32,115,117,98,115,101,113,117,101,110,116,115,101,99 +,111,110,100,32,108,97,114,103,101,115,116,118,101,114,121,32,105,109,112,111, +114,116,97,110,116,115,112,101,99,105,102,105,99,97,116,105,111,110,115,115,117, +114,102,97,99,101,32,111,102,32,116,104,101,97,112,112,108,105,101,100,32,116, +111,32,116,104,101,102,111,114,101,105,103,110,32,112,111,108,105,99,121,95,115, +101,116,68,111,109,97,105,110,78,97,109,101,101,115,116,97,98,108,105,115,104, +101,100,32,105,110,105,115,32,98,101,108,105,101,118,101,100,32,116,111,73,110, +32,97,100,100,105,116,105,111,110,32,116,111,109,101,97,110,105,110,103,32,111, +102,32,116,104,101,105,115,32,110,97,109,101,100,32,97,102,116,101,114,116,111, +32,112,114,111,116,101,99,116,32,116,104,101,105,115,32,114,101,112,114,101,115, +101,110,116,101,100,68,101,99,108,97,114,97,116,105,111,110,32,111,102,109,111, +114,101,32,101,102,102,105,99,105,101,110,116,67,108,97,115,115,105,102,105,99, +97,116,105,111,110,111,116,104,101,114,32,102,111,114,109,115,32,111,102,104,101 +,32,114,101,116,117,114,110,101,100,32,116,111,60,115,112,97,110,32,99,108,97, +115,115,61,34,99,112,101,114,102,111,114,109,97,110,99,101,32,111,102,40,102,117 +,110,99,116,105,111,110,40,41,32,123,13,105,102,32,97,110,100,32,111,110,108,121 +,32,105,102,114,101,103,105,111,110,115,32,111,102,32,116,104,101,108,101,97,100 +,105,110,103,32,116,111,32,116,104,101,114,101,108,97,116,105,111,110,115,32,119 +,105,116,104,85,110,105,116,101,100,32,78,97,116,105,111,110,115,115,116,121,108 +,101,61,34,104,101,105,103,104,116,58,111,116,104,101,114,32,116,104,97,110,32, +116,104,101,121,112,101,34,32,99,111,110,116,101,110,116,61,34,65,115,115,111,99 +,105,97,116,105,111,110,32,111,102,10,60,47,104,101,97,100,62,10,60,98,111,100, +121,108,111,99,97,116,101,100,32,111,110,32,116,104,101,105,115,32,114,101,102, +101,114,114,101,100,32,116,111,40,105,110,99,108,117,100,105,110,103,32,116,104, +101,99,111,110,99,101,110,116,114,97,116,105,111,110,115,116,104,101,32,105,110, +100,105,118,105,100,117,97,108,97,109,111,110,103,32,116,104,101,32,109,111,115, +116,116,104,97,110,32,97,110,121,32,111,116,104,101,114,47,62,10,60,108,105,110, +107,32,114,101,108,61,34,32,114,101,116,117,114,110,32,102,97,108,115,101,59,116 +,104,101,32,112,117,114,112,111,115,101,32,111,102,116,104,101,32,97,98,105,108, +105,116,121,32,116,111,59,99,111,108,111,114,58,35,102,102,102,125,10,46,10,60, +115,112,97,110,32,99,108,97,115,115,61,34,116,104,101,32,115,117,98,106,101,99, +116,32,111,102,100,101,102,105,110,105,116,105,111,110,115,32,111,102,62,13,10, +60,108,105,110,107,32,114,101,108,61,34,99,108,97,105,109,32,116,104,97,116,32, +116,104,101,104,97,118,101,32,100,101,118,101,108,111,112,101,100,60,116,97,98, +108,101,32,119,105,100,116,104,61,34,99,101,108,101,98,114,97,116,105,111,110,32 +,111,102,70,111,108,108,111,119,105,110,103,32,116,104,101,32,116,111,32,100,105 +,115,116,105,110,103,117,105,115,104,60,115,112,97,110,32,99,108,97,115,115,61, +34,98,116,97,107,101,115,32,112,108,97,99,101,32,105,110,117,110,100,101,114,32, +116,104,101,32,110,97,109,101,110,111,116,101,100,32,116,104,97,116,32,116,104, +101,62,60,33,91,101,110,100,105,102,93,45,45,62,10,115,116,121,108,101,61,34,109 +,97,114,103,105,110,45,105,110,115,116,101,97,100,32,111,102,32,116,104,101,105, +110,116,114,111,100,117,99,101,100,32,116,104,101,116,104,101,32,112,114,111,99, +101,115,115,32,111,102,105,110,99,114,101,97,115,105,110,103,32,116,104,101,100, +105,102,102,101,114,101,110,99,101,115,32,105,110,101,115,116,105,109,97,116,101 +,100,32,116,104,97,116,101,115,112,101,99,105,97,108,108,121,32,116,104,101,47, +100,105,118,62,60,100,105,118,32,105,100,61,34,119,97,115,32,101,118,101,110,116 +,117,97,108,108,121,116,104,114,111,117,103,104,111,117,116,32,104,105,115,116, +104,101,32,100,105,102,102,101,114,101,110,99,101,115,111,109,101,116,104,105, +110,103,32,116,104,97,116,115,112,97,110,62,60,47,115,112,97,110,62,60,47,115, +105,103,110,105,102,105,99,97,110,116,108,121,32,62,60,47,115,99,114,105,112,116 +,62,13,10,13,10,101,110,118,105,114,111,110,109,101,110,116,97,108,32,116,111,32 +,112,114,101,118,101,110,116,32,116,104,101,104,97,118,101,32,98,101,101,110,32, +117,115,101,100,101,115,112,101,99,105,97,108,108,121,32,102,111,114,117,110,100 +,101,114,115,116,97,110,100,32,116,104,101,105,115,32,101,115,115,101,110,116, +105,97,108,108,121,119,101,114,101,32,116,104,101,32,102,105,114,115,116,105,115 +,32,116,104,101,32,108,97,114,103,101,115,116,104,97,118,101,32,98,101,101,110, +32,109,97,100,101,34,32,115,114,99,61,34,104,116,116,112,58,47,47,105,110,116, +101,114,112,114,101,116,101,100,32,97,115,115,101,99,111,110,100,32,104,97,108, +102,32,111,102,99,114,111,108,108,105,110,103,61,34,110,111,34,32,105,115,32,99, +111,109,112,111,115,101,100,32,111,102,73,73,44,32,72,111,108,121,32,82,111,109, +97,110,105,115,32,101,120,112,101,99,116,101,100,32,116,111,104,97,118,101,32, +116,104,101,105,114,32,111,119,110,100,101,102,105,110,101,100,32,97,115,32,116, +104,101,116,114,97,100,105,116,105,111,110,97,108,108,121,32,104,97,118,101,32, +100,105,102,102,101,114,101,110,116,97,114,101,32,111,102,116,101,110,32,117,115 +,101,100,116,111,32,101,110,115,117,114,101,32,116,104,97,116,97,103,114,101,101 +,109,101,110,116,32,119,105,116,104,99,111,110,116,97,105,110,105,110,103,32,116 +,104,101,97,114,101,32,102,114,101,113,117,101,110,116,108,121,105,110,102,111, +114,109,97,116,105,111,110,32,111,110,101,120,97,109,112,108,101,32,105,115,32, +116,104,101,114,101,115,117,108,116,105,110,103,32,105,110,32,97,60,47,97,62,60, +47,108,105,62,60,47,117,108,62,32,99,108,97,115,115,61,34,102,111,111,116,101, +114,97,110,100,32,101,115,112,101,99,105,97,108,108,121,116,121,112,101,61,34,98 +,117,116,116,111,110,34,32,60,47,115,112,97,110,62,60,47,115,112,97,110,62,119, +104,105,99,104,32,105,110,99,108,117,100,101,100,62,10,60,109,101,116,97,32,110, +97,109,101,61,34,99,111,110,115,105,100,101,114,101,100,32,116,104,101,99,97,114 +,114,105,101,100,32,111,117,116,32,98,121,72,111,119,101,118,101,114,44,32,105, +116,32,105,115,98,101,99,97,109,101,32,112,97,114,116,32,111,102,105,110,32,114, +101,108,97,116,105,111,110,32,116,111,112,111,112,117,108,97,114,32,105,110,32, +116,104,101,116,104,101,32,99,97,112,105,116,97,108,32,111,102,119,97,115,32,111 +,102,102,105,99,105,97,108,108,121,119,104,105,99,104,32,104,97,115,32,98,101, +101,110,116,104,101,32,72,105,115,116,111,114,121,32,111,102,97,108,116,101,114, +110,97,116,105,118,101,32,116,111,100,105,102,102,101,114,101,110,116,32,102,114 +,111,109,116,111,32,115,117,112,112,111,114,116,32,116,104,101,115,117,103,103, +101,115,116,101,100,32,116,104,97,116,105,110,32,116,104,101,32,112,114,111,99, +101,115,115,32,32,60,100,105,118,32,99,108,97,115,115,61,34,116,104,101,32,102, +111,117,110,100,97,116,105,111,110,98,101,99,97,117,115,101,32,111,102,32,104, +105,115,99,111,110,99,101,114,110,101,100,32,119,105,116,104,116,104,101,32,117, +110,105,118,101,114,115,105,116,121,111,112,112,111,115,101,100,32,116,111,32, +116,104,101,116,104,101,32,99,111,110,116,101,120,116,32,111,102,60,115,112,97, +110,32,99,108,97,115,115,61,34,112,116,101,120,116,34,32,110,97,109,101,61,34, +113,34,9,9,60,100,105,118,32,99,108,97,115,115,61,34,116,104,101,32,115,99,105, +101,110,116,105,102,105,99,114,101,112,114,101,115,101,110,116,101,100,32,98,121 +,109,97,116,104,101,109,97,116,105,99,105,97,110,115,101,108,101,99,116,101,100, +32,98,121,32,116,104,101,116,104,97,116,32,104,97,118,101,32,98,101,101,110,62, +60,100,105,118,32,99,108,97,115,115,61,34,99,100,105,118,32,105,100,61,34,104, +101,97,100,101,114,105,110,32,112,97,114,116,105,99,117,108,97,114,44,99,111,110 +,118,101,114,116,101,100,32,105,110,116,111,41,59,10,60,47,115,99,114,105,112, +116,62,10,60,112,104,105,108,111,115,111,112,104,105,99,97,108,32,115,114,112, +115,107,111,104,114,118,97,116,115,107,105,116,105,225,186,191,110,103,32,86,105 +,225,187,135,116,208,160,209,131,209,129,209,129,208,186,208,184,208,185,209,128 +,209,131,209,129,209,129,208,186,208,184,208,185,105,110,118,101,115,116,105,103 +,97,99,105,195,179,110,112,97,114,116,105,99,105,112,97,99,105,195,179,110,208, +186,208,190,209,130,208,190,209,128,209,139,208,181,208,190,208,177,208,187,208, +176,209,129,209,130,208,184,208,186,208,190,209,130,208,190,209,128,209,139,208, +185,209,135,208,181,208,187,208,190,208,178,208,181,208,186,209,129,208,184,209, +129,209,130,208,181,208,188,209,139,208,157,208,190,208,178,208,190,209,129,209, +130,208,184,208,186,208,190,209,130,208,190,209,128,209,139,209,133,208,190,208, +177,208,187,208,176,209,129,209,130,209,140,208,178,209,128,208,181,208,188,208, +181,208,189,208,184,208,186,208,190,209,130,208,190,209,128,208,176,209,143,209, +129,208,181,208,179,208,190,208,180,208,189,209,143,209,129,208,186,208,176,209, +135,208,176,209,130,209,140,208,189,208,190,208,178,208,190,209,129,209,130,208, +184,208,163,208,186,209,128,208,176,208,184,208,189,209,139,208,178,208,190,208, +191,209,128,208,190,209,129,209,139,208,186,208,190,209,130,208,190,209,128,208, +190,208,185,209,129,208,180,208,181,208,187,208,176,209,130,209,140,208,191,208, +190,208,188,208,190,209,137,209,140,209,142,209,129,209,128,208,181,208,180,209, +129,209,130,208,178,208,190,208,177,209,128,208,176,208,183,208,190,208,188,209, +129,209,130,208,190,209,128,208,190,208,189,209,139,209,131,209,135,208,176,209, +129,209,130,208,184,208,181,209,130,208,181,209,135,208,181,208,189,208,184,208, +181,208,147,208,187,208,176,208,178,208,189,208,176,209,143,208,184,209,129,209, +130,208,190,209,128,208,184,208,184,209,129,208,184,209,129,209,130,208,181,208, +188,208,176,209,128,208,181,209,136,208,181,208,189,208,184,209,143,208,161,208, +186,208,176,209,135,208,176,209,130,209,140,208,191,208,190,209,141,209,130,208, +190,208,188,209,131,209,129,208,187,208,181,208,180,209,131,208,181,209,130,209, +129,208,186,208,176,208,183,208,176,209,130,209,140,209,130,208,190,208,178,208, +176,209,128,208,190,208,178,208,186,208,190,208,189,208,181,209,135,208,189,208, +190,209,128,208,181,209,136,208,181,208,189,208,184,208,181,208,186,208,190,209, +130,208,190,209,128,208,190,208,181,208,190,209,128,208,179,208,176,208,189,208, +190,208,178,208,186,208,190,209,130,208,190,209,128,208,190,208,188,208,160,208, +181,208,186,208,187,208,176,208,188,208,176,216,167,217,132,217,133,217,134,216, +170,216,175,217,137,217,133,217,134,216,170,216,175,217,138,216,167,216,170,216, +167,217,132,217,133,217,136,216,182,217,136,216,185,216,167,217,132,216,168,216, +177,216,167,217,133,216,172,216,167,217,132,217,133,217,136,216,167,217,130,216, +185,216,167,217,132,216,177,216,179,216,167,216,166,217,132,217,133,216,180,216, +167,216,177,217,131,216,167,216,170,216,167,217,132,216,163,216,185,216,182,216, +167,216,161,216,167,217,132,216,177,217,138,216,167,216,182,216,169,216,167,217, +132,216,170,216,181,217,133,217,138,217,133,216,167,217,132,216,167,216,185,216, +182,216,167,216,161,216,167,217,132,217,134,216,170,216,167,216,166,216,172,216, +167,217,132,216,163,217,132,216,185,216,167,216,168,216,167,217,132,216,170,216, +179,216,172,217,138,217,132,216,167,217,132,216,163,217,130,216,179,216,167,217, +133,216,167,217,132,216,182,216,186,216,183,216,167,216,170,216,167,217,132,217, +129,217,138,216,175,217,138,217,136,216,167,217,132,216,170,216,177,216,173,217, +138,216,168,216,167,217,132,216,172,216,175,217,138,216,175,216,169,216,167,217, +132,216,170,216,185,217,132,217,138,217,133,216,167,217,132,216,163,216,174,216, +168,216,167,216,177,216,167,217,132,216,167,217,129,217,132,216,167,217,133,216, +167,217,132,216,163,217,129,217,132,216,167,217,133,216,167,217,132,216,170,216, +167,216,177,217,138,216,174,216,167,217,132,216,170,217,130,217,134,217,138,216, +169,216,167,217,132,216,167,217,132,216,185,216,167,216,168,216,167,217,132,216, +174,217,136,216,167,216,183,216,177,216,167,217,132,217,133,216,172,216,170,217, +133,216,185,216,167,217,132,216,175,217,138,217,131,217,136,216,177,216,167,217, +132,216,179,217,138,216,167,216,173,216,169,216,185,216,168,216,175,216,167,217, +132,217,132,217,135,216,167,217,132,216,170,216,177,216,168,217,138,216,169,216, +167,217,132,216,177,217,136,216,167,216,168,216,183,216,167,217,132,216,163,216, +175,216,168,217,138,216,169,216,167,217,132,216,167,216,174,216,168,216,167,216, +177,216,167,217,132,217,133,216,170,216,173,216,175,216,169,216,167,217,132,216, +167,216,186,216,167,217,134,217,138,99,117,114,115,111,114,58,112,111,105,110, +116,101,114,59,60,47,116,105,116,108,101,62,10,60,109,101,116,97,32,34,32,104, +114,101,102,61,34,104,116,116,112,58,47,47,34,62,60,115,112,97,110,32,99,108,97, +115,115,61,34,109,101,109,98,101,114,115,32,111,102,32,116,104,101,32,119,105, +110,100,111,119,46,108,111,99,97,116,105,111,110,118,101,114,116,105,99,97,108, +45,97,108,105,103,110,58,47,97,62,32,124,32,60,97,32,104,114,101,102,61,34,60,33 +,100,111,99,116,121,112,101,32,104,116,109,108,62,109,101,100,105,97,61,34,115, +99,114,101,101,110,34,32,60,111,112,116,105,111,110,32,118,97,108,117,101,61,34, +102,97,118,105,99,111,110,46,105,99,111,34,32,47,62,10,9,9,60,100,105,118,32,99, +108,97,115,115,61,34,99,104,97,114,97,99,116,101,114,105,115,116,105,99,115,34, +32,109,101,116,104,111,100,61,34,103,101,116,34,32,47,98,111,100,121,62,10,60,47 +,104,116,109,108,62,10,115,104,111,114,116,99,117,116,32,105,99,111,110,34,32, +100,111,99,117,109,101,110,116,46,119,114,105,116,101,40,112,97,100,100,105,110, +103,45,98,111,116,116,111,109,58,114,101,112,114,101,115,101,110,116,97,116,105, +118,101,115,115,117,98,109,105,116,34,32,118,97,108,117,101,61,34,97,108,105,103 +,110,61,34,99,101,110,116,101,114,34,32,116,104,114,111,117,103,104,111,117,116, +32,116,104,101,32,115,99,105,101,110,99,101,32,102,105,99,116,105,111,110,10,32, +32,60,100,105,118,32,99,108,97,115,115,61,34,115,117,98,109,105,116,34,32,99,108 +,97,115,115,61,34,111,110,101,32,111,102,32,116,104,101,32,109,111,115,116,32, +118,97,108,105,103,110,61,34,116,111,112,34,62,60,119,97,115,32,101,115,116,97, +98,108,105,115,104,101,100,41,59,13,10,60,47,115,99,114,105,112,116,62,13,10,114 +,101,116,117,114,110,32,102,97,108,115,101,59,34,62,41,46,115,116,121,108,101,46 +,100,105,115,112,108,97,121,98,101,99,97,117,115,101,32,111,102,32,116,104,101, +32,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,60,102,111,114,109, +32,97,99,116,105,111,110,61,34,47,125,98,111,100,121,123,109,97,114,103,105,110, +58,48,59,69,110,99,121,99,108,111,112,101,100,105,97,32,111,102,118,101,114,115, +105,111,110,32,111,102,32,116,104,101,32,46,99,114,101,97,116,101,69,108,101,109 +,101,110,116,40,110,97,109,101,34,32,99,111,110,116,101,110,116,61,34,60,47,100, +105,118,62,10,60,47,100,105,118,62,10,10,97,100,109,105,110,105,115,116,114,97, +116,105,118,101,32,60,47,98,111,100,121,62,10,60,47,104,116,109,108,62,104,105, +115,116,111,114,121,32,111,102,32,116,104,101,32,34,62,60,105,110,112,117,116,32 +,116,121,112,101,61,34,112,111,114,116,105,111,110,32,111,102,32,116,104,101,32, +97,115,32,112,97,114,116,32,111,102,32,116,104,101,32,38,110,98,115,112,59,60,97 +,32,104,114,101,102,61,34,111,116,104,101,114,32,99,111,117,110,116,114,105,101, +115,34,62,10,60,100,105,118,32,99,108,97,115,115,61,34,60,47,115,112,97,110,62, +60,47,115,112,97,110,62,60,73,110,32,111,116,104,101,114,32,119,111,114,100,115, +44,100,105,115,112,108,97,121,58,32,98,108,111,99,107,59,99,111,110,116,114,111, +108,32,111,102,32,116,104,101,32,105,110,116,114,111,100,117,99,116,105,111,110, +32,111,102,47,62,10,60,109,101,116,97,32,110,97,109,101,61,34,97,115,32,119,101, +108,108,32,97,115,32,116,104,101,32,105,110,32,114,101,99,101,110,116,32,121,101 +,97,114,115,13,10,9,60,100,105,118,32,99,108,97,115,115,61,34,60,47,100,105,118, +62,10,9,60,47,100,105,118,62,10,105,110,115,112,105,114,101,100,32,98,121,32,116 +,104,101,116,104,101,32,101,110,100,32,111,102,32,116,104,101,32,99,111,109,112, +97,116,105,98,108,101,32,119,105,116,104,98,101,99,97,109,101,32,107,110,111,119 +,110,32,97,115,32,115,116,121,108,101,61,34,109,97,114,103,105,110,58,46,106,115 +,34,62,60,47,115,99,114,105,112,116,62,60,32,73,110,116,101,114,110,97,116,105, +111,110,97,108,32,116,104,101,114,101,32,104,97,118,101,32,98,101,101,110,71,101 +,114,109,97,110,32,108,97,110,103,117,97,103,101,32,115,116,121,108,101,61,34,99 +,111,108,111,114,58,35,67,111,109,109,117,110,105,115,116,32,80,97,114,116,121, +99,111,110,115,105,115,116,101,110,116,32,119,105,116,104,98,111,114,100,101,114 +,61,34,48,34,32,99,101,108,108,32,109,97,114,103,105,110,104,101,105,103,104,116 +,61,34,116,104,101,32,109,97,106,111,114,105,116,121,32,111,102,34,32,97,108,105 +,103,110,61,34,99,101,110,116,101,114,114,101,108,97,116,101,100,32,116,111,32, +116,104,101,32,109,97,110,121,32,100,105,102,102,101,114,101,110,116,32,79,114, +116,104,111,100,111,120,32,67,104,117,114,99,104,115,105,109,105,108,97,114,32, +116,111,32,116,104,101,32,47,62,10,60,108,105,110,107,32,114,101,108,61,34,115, +119,97,115,32,111,110,101,32,111,102,32,116,104,101,32,117,110,116,105,108,32, +104,105,115,32,100,101,97,116,104,125,41,40,41,59,10,60,47,115,99,114,105,112, +116,62,111,116,104,101,114,32,108,97,110,103,117,97,103,101,115,99,111,109,112, +97,114,101,100,32,116,111,32,116,104,101,112,111,114,116,105,111,110,115,32,111, +102,32,116,104,101,116,104,101,32,78,101,116,104,101,114,108,97,110,100,115,116, +104,101,32,109,111,115,116,32,99,111,109,109,111,110,98,97,99,107,103,114,111, +117,110,100,58,117,114,108,40,97,114,103,117,101,100,32,116,104,97,116,32,116, +104,101,115,99,114,111,108,108,105,110,103,61,34,110,111,34,32,105,110,99,108, +117,100,101,100,32,105,110,32,116,104,101,78,111,114,116,104,32,65,109,101,114, +105,99,97,110,32,116,104,101,32,110,97,109,101,32,111,102,32,116,104,101,105,110 +,116,101,114,112,114,101,116,97,116,105,111,110,115,116,104,101,32,116,114,97, +100,105,116,105,111,110,97,108,100,101,118,101,108,111,112,109,101,110,116,32, +111,102,32,102,114,101,113,117,101,110,116,108,121,32,117,115,101,100,97,32,99, +111,108,108,101,99,116,105,111,110,32,111,102,118,101,114,121,32,115,105,109,105 +,108,97,114,32,116,111,115,117,114,114,111,117,110,100,105,110,103,32,116,104, +101,101,120,97,109,112,108,101,32,111,102,32,116,104,105,115,97,108,105,103,110, +61,34,99,101,110,116,101,114,34,62,119,111,117,108,100,32,104,97,118,101,32,98, +101,101,110,105,109,97,103,101,95,99,97,112,116,105,111,110,32,61,97,116,116,97, +99,104,101,100,32,116,111,32,116,104,101,115,117,103,103,101,115,116,105,110,103 +,32,116,104,97,116,105,110,32,116,104,101,32,102,111,114,109,32,111,102,32,105, +110,118,111,108,118,101,100,32,105,110,32,116,104,101,105,115,32,100,101,114,105 +,118,101,100,32,102,114,111,109,110,97,109,101,100,32,97,102,116,101,114,32,116, +104,101,73,110,116,114,111,100,117,99,116,105,111,110,32,116,111,114,101,115,116 +,114,105,99,116,105,111,110,115,32,111,110,32,115,116,121,108,101,61,34,119,105, +100,116,104,58,32,99,97,110,32,98,101,32,117,115,101,100,32,116,111,32,116,104, +101,32,99,114,101,97,116,105,111,110,32,111,102,109,111,115,116,32,105,109,112, +111,114,116,97,110,116,32,105,110,102,111,114,109,97,116,105,111,110,32,97,110, +100,114,101,115,117,108,116,101,100,32,105,110,32,116,104,101,99,111,108,108,97, +112,115,101,32,111,102,32,116,104,101,84,104,105,115,32,109,101,97,110,115,32, +116,104,97,116,101,108,101,109,101,110,116,115,32,111,102,32,116,104,101,119,97, +115,32,114,101,112,108,97,99,101,100,32,98,121,97,110,97,108,121,115,105,115,32, +111,102,32,116,104,101,105,110,115,112,105,114,97,116,105,111,110,32,102,111,114 +,114,101,103,97,114,100,101,100,32,97,115,32,116,104,101,109,111,115,116,32,115, +117,99,99,101,115,115,102,117,108,107,110,111,119,110,32,97,115,32,38,113,117, +111,116,59,97,32,99,111,109,112,114,101,104,101,110,115,105,118,101,72,105,115, +116,111,114,121,32,111,102,32,116,104,101,32,119,101,114,101,32,99,111,110,115, +105,100,101,114,101,100,114,101,116,117,114,110,101,100,32,116,111,32,116,104, +101,97,114,101,32,114,101,102,101,114,114,101,100,32,116,111,85,110,115,111,117, +114,99,101,100,32,105,109,97,103,101,62,10,9,60,100,105,118,32,99,108,97,115,115 +,61,34,99,111,110,115,105,115,116,115,32,111,102,32,116,104,101,115,116,111,112, +80,114,111,112,97,103,97,116,105,111,110,105,110,116,101,114,101,115,116,32,105, +110,32,116,104,101,97,118,97,105,108,97,98,105,108,105,116,121,32,111,102,97,112 +,112,101,97,114,115,32,116,111,32,104,97,118,101,101,108,101,99,116,114,111,109, +97,103,110,101,116,105,99,101,110,97,98,108,101,83,101,114,118,105,99,101,115,40 +,102,117,110,99,116,105,111,110,32,111,102,32,116,104,101,73,116,32,105,115,32, +105,109,112,111,114,116,97,110,116,60,47,115,99,114,105,112,116,62,60,47,100,105 +,118,62,102,117,110,99,116,105,111,110,40,41,123,118,97,114,32,114,101,108,97, +116,105,118,101,32,116,111,32,116,104,101,97,115,32,97,32,114,101,115,117,108, +116,32,111,102,32,116,104,101,32,112,111,115,105,116,105,111,110,32,111,102,70, +111,114,32,101,120,97,109,112,108,101,44,32,105,110,32,109,101,116,104,111,100, +61,34,112,111,115,116,34,32,119,97,115,32,102,111,108,108,111,119,101,100,32,98, +121,38,97,109,112,59,109,100,97,115,104,59,32,116,104,101,116,104,101,32,97,112, +112,108,105,99,97,116,105,111,110,106,115,34,62,60,47,115,99,114,105,112,116,62, +13,10,117,108,62,60,47,100,105,118,62,60,47,100,105,118,62,97,102,116,101,114,32 +,116,104,101,32,100,101,97,116,104,119,105,116,104,32,114,101,115,112,101,99,116 +,32,116,111,115,116,121,108,101,61,34,112,97,100,100,105,110,103,58,105,115,32, +112,97,114,116,105,99,117,108,97,114,108,121,100,105,115,112,108,97,121,58,105, +110,108,105,110,101,59,32,116,121,112,101,61,34,115,117,98,109,105,116,34,32,105 +,115,32,100,105,118,105,100,101,100,32,105,110,116,111,228,184,173,230,150,135, +32,40,231,174,128,228,189,147,41,114,101,115,112,111,110,115,97,98,105,108,105, +100,97,100,97,100,109,105,110,105,115,116,114,97,99,105,195,179,110,105,110,116, +101,114,110,97,99,105,111,110,97,108,101,115,99,111,114,114,101,115,112,111,110, +100,105,101,110,116,101,224,164,137,224,164,170,224,164,175,224,165,139,224,164, +151,224,164,170,224,165,130,224,164,176,224,165,141,224,164,181,224,164,185,224, +164,174,224,164,190,224,164,176,224,165,135,224,164,178,224,165,139,224,164,151, +224,165,139,224,164,130,224,164,154,224,165,129,224,164,168,224,164,190,224,164, +181,224,164,178,224,165,135,224,164,149,224,164,191,224,164,168,224,164,184,224, +164,176,224,164,149,224,164,190,224,164,176,224,164,170,224,165,129,224,164,178, +224,164,191,224,164,184,224,164,150,224,165,139,224,164,156,224,165,135,224,164, +130,224,164,154,224,164,190,224,164,185,224,164,191,224,164,143,224,164,173,224, +165,135,224,164,156,224,165,135,224,164,130,224,164,182,224,164,190,224,164,174, +224,164,191,224,164,178,224,164,185,224,164,174,224,164,190,224,164,176,224,165, +128,224,164,156,224,164,190,224,164,151,224,164,176,224,164,163,224,164,172,224, +164,168,224,164,190,224,164,168,224,165,135,224,164,149,224,165,129,224,164,174, +224,164,190,224,164,176,224,164,172,224,165,141,224,164,178,224,165,137,224,164, +151,224,164,174,224,164,190,224,164,178,224,164,191,224,164,149,224,164,174,224, +164,185,224,164,191,224,164,178,224,164,190,224,164,170,224,165,131,224,164,183, +224,165,141,224,164,160,224,164,172,224,164,162,224,164,188,224,164,164,224,165, +135,224,164,173,224,164,190,224,164,156,224,164,170,224,164,190,224,164,149,224, +165,141,224,164,178,224,164,191,224,164,149,224,164,159,224,165,141,224,164,176, +224,165,135,224,164,168,224,164,150,224,164,191,224,164,178,224,164,190,224,164, +171,224,164,166,224,165,140,224,164,176,224,164,190,224,164,168,224,164,174,224, +164,190,224,164,174,224,164,178,224,165,135,224,164,174,224,164,164,224,164,166, +224,164,190,224,164,168,224,164,172,224,164,190,224,164,156,224,164,190,224,164, +176,224,164,181,224,164,191,224,164,149,224,164,190,224,164,184,224,164,149,224, +165,141,224,164,175,224,165,139,224,164,130,224,164,154,224,164,190,224,164,185, +224,164,164,224,165,135,224,164,170,224,164,185,224,165,129,224,164,129,224,164, +154,224,164,172,224,164,164,224,164,190,224,164,175,224,164,190,224,164,184,224, +164,130,224,164,181,224,164,190,224,164,166,224,164,166,224,165,135,224,164,150, +224,164,168,224,165,135,224,164,170,224,164,191,224,164,155,224,164,178,224,165, +135,224,164,181,224,164,191,224,164,182,224,165,135,224,164,183,224,164,176,224, +164,190,224,164,156,224,165,141,224,164,175,224,164,137,224,164,164,224,165,141, +224,164,164,224,164,176,224,164,174,224,165,129,224,164,130,224,164,172,224,164, +136,224,164,166,224,165,139,224,164,168,224,165,139,224,164,130,224,164,137,224, +164,170,224,164,149,224,164,176,224,164,163,224,164,170,224,164,162,224,164,188, +224,165,135,224,164,130,224,164,184,224,165,141,224,164,165,224,164,191,224,164, +164,224,164,171,224,164,191,224,164,178,224,165,141,224,164,174,224,164,174,224, +165,129,224,164,150,224,165,141,224,164,175,224,164,133,224,164,154,224,165,141, +224,164,155,224,164,190,224,164,155,224,165,130,224,164,159,224,164,164,224,165, +128,224,164,184,224,164,130,224,164,151,224,165,128,224,164,164,224,164,156,224, +164,190,224,164,143,224,164,151,224,164,190,224,164,181,224,164,191,224,164,173, +224,164,190,224,164,151,224,164,152,224,164,163,224,165,141,224,164,159,224,165, +135,224,164,166,224,165,130,224,164,184,224,164,176,224,165,135,224,164,166,224, +164,191,224,164,168,224,165,139,224,164,130,224,164,185,224,164,164,224,165,141, +224,164,175,224,164,190,224,164,184,224,165,135,224,164,149,224,165,141,224,164, +184,224,164,151,224,164,190,224,164,130,224,164,167,224,165,128,224,164,181,224, +164,191,224,164,182,224,165,141,224,164,181,224,164,176,224,164,190,224,164,164, +224,165,135,224,164,130,224,164,166,224,165,136,224,164,159,224,165,141,224,164, +184,224,164,168,224,164,149,224,165,141,224,164,182,224,164,190,224,164,184,224, +164,190,224,164,174,224,164,168,224,165,135,224,164,133,224,164,166,224,164,190, +224,164,178,224,164,164,224,164,172,224,164,191,224,164,156,224,164,178,224,165, +128,224,164,170,224,165,129,224,164,176,224,165,130,224,164,183,224,164,185,224, +164,191,224,164,130,224,164,166,224,165,128,224,164,174,224,164,191,224,164,164, +224,165,141,224,164,176,224,164,149,224,164,181,224,164,191,224,164,164,224,164, +190,224,164,176,224,165,129,224,164,170,224,164,175,224,165,135,224,164,184,224, +165,141,224,164,165,224,164,190,224,164,168,224,164,149,224,164,176,224,165,139, +224,164,161,224,164,188,224,164,174,224,165,129,224,164,149,224,165,141,224,164, +164,224,164,175,224,165,139,224,164,156,224,164,168,224,164,190,224,164,149,224, +165,131,224,164,170,224,164,175,224,164,190,224,164,170,224,165,139,224,164,184, +224,165,141,224,164,159,224,164,152,224,164,176,224,165,135,224,164,178,224,165, +130,224,164,149,224,164,190,224,164,176,224,165,141,224,164,175,224,164,181,224, +164,191,224,164,154,224,164,190,224,164,176,224,164,184,224,165,130,224,164,154, +224,164,168,224,164,190,224,164,174,224,165,130,224,164,178,224,165,141,224,164, +175,224,164,166,224,165,135,224,164,150,224,165,135,224,164,130,224,164,185,224, +164,174,224,165,135,224,164,182,224,164,190,224,164,184,224,165,141,224,164,149, +224,165,130,224,164,178,224,164,174,224,165,136,224,164,130,224,164,168,224,165, +135,224,164,164,224,165,136,224,164,175,224,164,190,224,164,176,224,164,156,224, +164,191,224,164,184,224,164,149,224,165,135,114,115,115,43,120,109,108,34,32,116 +,105,116,108,101,61,34,45,116,121,112,101,34,32,99,111,110,116,101,110,116,61,34 +,116,105,116,108,101,34,32,99,111,110,116,101,110,116,61,34,97,116,32,116,104, +101,32,115,97,109,101,32,116,105,109,101,46,106,115,34,62,60,47,115,99,114,105, +112,116,62,10,60,34,32,109,101,116,104,111,100,61,34,112,111,115,116,34,32,60,47 +,115,112,97,110,62,60,47,97,62,60,47,108,105,62,118,101,114,116,105,99,97,108,45 +,97,108,105,103,110,58,116,47,106,113,117,101,114,121,46,109,105,110,46,106,115, +34,62,46,99,108,105,99,107,40,102,117,110,99,116,105,111,110,40,32,115,116,121, +108,101,61,34,112,97,100,100,105,110,103,45,125,41,40,41,59,10,60,47,115,99,114, +105,112,116,62,10,60,47,115,112,97,110,62,60,97,32,104,114,101,102,61,34,60,97, +32,104,114,101,102,61,34,104,116,116,112,58,47,47,41,59,32,114,101,116,117,114, +110,32,102,97,108,115,101,59,116,101,120,116,45,100,101,99,111,114,97,116,105, +111,110,58,32,115,99,114,111,108,108,105,110,103,61,34,110,111,34,32,98,111,114, +100,101,114,45,99,111,108,108,97,112,115,101,58,97,115,115,111,99,105,97,116,101 +,100,32,119,105,116,104,32,66,97,104,97,115,97,32,73,110,100,111,110,101,115,105 +,97,69,110,103,108,105,115,104,32,108,97,110,103,117,97,103,101,60,116,101,120, +116,32,120,109,108,58,115,112,97,99,101,61,46,103,105,102,34,32,98,111,114,100, +101,114,61,34,48,34,60,47,98,111,100,121,62,10,60,47,104,116,109,108,62,10,111, +118,101,114,102,108,111,119,58,104,105,100,100,101,110,59,105,109,103,32,115,114 +,99,61,34,104,116,116,112,58,47,47,97,100,100,69,118,101,110,116,76,105,115,116, +101,110,101,114,114,101,115,112,111,110,115,105,98,108,101,32,102,111,114,32,115 +,46,106,115,34,62,60,47,115,99,114,105,112,116,62,10,47,102,97,118,105,99,111, +110,46,105,99,111,34,32,47,62,111,112,101,114,97,116,105,110,103,32,115,121,115, +116,101,109,34,32,115,116,121,108,101,61,34,119,105,100,116,104,58,49,116,97,114 +,103,101,116,61,34,95,98,108,97,110,107,34,62,83,116,97,116,101,32,85,110,105, +118,101,114,115,105,116,121,116,101,120,116,45,97,108,105,103,110,58,108,101,102 +,116,59,10,100,111,99,117,109,101,110,116,46,119,114,105,116,101,40,44,32,105, +110,99,108,117,100,105,110,103,32,116,104,101,32,97,114,111,117,110,100,32,116, +104,101,32,119,111,114,108,100,41,59,13,10,60,47,115,99,114,105,112,116,62,13,10 +,60,34,32,115,116,121,108,101,61,34,104,101,105,103,104,116,58,59,111,118,101, +114,102,108,111,119,58,104,105,100,100,101,110,109,111,114,101,32,105,110,102, +111,114,109,97,116,105,111,110,97,110,32,105,110,116,101,114,110,97,116,105,111, +110,97,108,97,32,109,101,109,98,101,114,32,111,102,32,116,104,101,32,111,110,101 +,32,111,102,32,116,104,101,32,102,105,114,115,116,99,97,110,32,98,101,32,102,111 +,117,110,100,32,105,110,32,60,47,100,105,118,62,10,9,9,60,47,100,105,118,62,10, +100,105,115,112,108,97,121,58,32,110,111,110,101,59,34,62,34,32,47,62,10,60,108, +105,110,107,32,114,101,108,61,34,10,32,32,40,102,117,110,99,116,105,111,110,40, +41,32,123,116,104,101,32,49,53,116,104,32,99,101,110,116,117,114,121,46,112,114, +101,118,101,110,116,68,101,102,97,117,108,116,40,108,97,114,103,101,32,110,117, +109,98,101,114,32,111,102,32,66,121,122,97,110,116,105,110,101,32,69,109,112,105 +,114,101,46,106,112,103,124,116,104,117,109,98,124,108,101,102,116,124,118,97, +115,116,32,109,97,106,111,114,105,116,121,32,111,102,109,97,106,111,114,105,116, +121,32,111,102,32,116,104,101,32,32,97,108,105,103,110,61,34,99,101,110,116,101, +114,34,62,85,110,105,118,101,114,115,105,116,121,32,80,114,101,115,115,100,111, +109,105,110,97,116,101,100,32,98,121,32,116,104,101,83,101,99,111,110,100,32,87, +111,114,108,100,32,87,97,114,100,105,115,116,114,105,98,117,116,105,111,110,32, +111,102,32,115,116,121,108,101,61,34,112,111,115,105,116,105,111,110,58,116,104, +101,32,114,101,115,116,32,111,102,32,116,104,101,32,99,104,97,114,97,99,116,101, +114,105,122,101,100,32,98,121,32,114,101,108,61,34,110,111,102,111,108,108,111, +119,34,62,100,101,114,105,118,101,115,32,102,114,111,109,32,116,104,101,114,97, +116,104,101,114,32,116,104,97,110,32,116,104,101,32,97,32,99,111,109,98,105,110, +97,116,105,111,110,32,111,102,115,116,121,108,101,61,34,119,105,100,116,104,58, +49,48,48,69,110,103,108,105,115,104,45,115,112,101,97,107,105,110,103,99,111,109 +,112,117,116,101,114,32,115,99,105,101,110,99,101,98,111,114,100,101,114,61,34, +48,34,32,97,108,116,61,34,116,104,101,32,101,120,105,115,116,101,110,99,101,32, +111,102,68,101,109,111,99,114,97,116,105,99,32,80,97,114,116,121,34,32,115,116, +121,108,101,61,34,109,97,114,103,105,110,45,70,111,114,32,116,104,105,115,32,114 +,101,97,115,111,110,44,46,106,115,34,62,60,47,115,99,114,105,112,116,62,10,9,115 +,66,121,84,97,103,78,97,109,101,40,115,41,91,48,93,106,115,34,62,60,47,115,99, +114,105,112,116,62,13,10,60,46,106,115,34,62,60,47,115,99,114,105,112,116,62,13, +10,108,105,110,107,32,114,101,108,61,34,105,99,111,110,34,32,39,32,97,108,116,61 +,39,39,32,99,108,97,115,115,61,39,102,111,114,109,97,116,105,111,110,32,111,102, +32,116,104,101,118,101,114,115,105,111,110,115,32,111,102,32,116,104,101,32,60, +47,97,62,60,47,100,105,118,62,60,47,100,105,118,62,47,112,97,103,101,62,10,32,32 +,60,112,97,103,101,62,10,60,100,105,118,32,99,108,97,115,115,61,34,99,111,110, +116,98,101,99,97,109,101,32,116,104,101,32,102,105,114,115,116,98,97,104,97,115, +97,32,73,110,100,111,110,101,115,105,97,101,110,103,108,105,115,104,32,40,115, +105,109,112,108,101,41,206,149,206,187,206,187,206,183,206,189,206,185,206,186, +206,172,209,133,209,128,208,178,208,176,209,130,209,129,208,186,208,184,208,186, +208,190,208,188,208,191,208,176,208,189,208,184,208,184,209,143,208,178,208,187, +209,143,208,181,209,130,209,129,209,143,208,148,208,190,208,177,208,176,208,178, +208,184,209,130,209,140,209,135,208,181,208,187,208,190,208,178,208,181,208,186, +208,176,209,128,208,176,208,183,208,178,208,184,209,130,208,184,209,143,208,152, +208,189,209,130,208,181,209,128,208,189,208,181,209,130,208,158,209,130,208,178, +208,181,209,130,208,184,209,130,209,140,208,189,208,176,208,191,209,128,208,184, +208,188,208,181,209,128,208,184,208,189,209,130,208,181,209,128,208,189,208,181, +209,130,208,186,208,190,209,130,208,190,209,128,208,190,208,179,208,190,209,129, +209,130,209,128,208,176,208,189,208,184,209,134,209,139,208,186,208,176,209,135, +208,181,209,129,209,130,208,178,208,181,209,131,209,129,208,187,208,190,208,178, +208,184,209,143,209,133,208,191,209,128,208,190,208,177,208,187,208,181,208,188, +209,139,208,191,208,190,208,187,209,131,209,135,208,184,209,130,209,140,209,143, +208,178,208,187,209,143,209,142,209,130,209,129,209,143,208,189,208,176,208,184, +208,177,208,190,208,187,208,181,208,181,208,186,208,190,208,188,208,191,208,176, +208,189,208,184,209,143,208,178,208,189,208,184,208,188,208,176,208,189,208,184, +208,181,209,129,209,128,208,181,208,180,209,129,209,130,208,178,208,176,216,167, +217,132,217,133,217,136,216,167,216,182,217,138,216,185,216,167,217,132,216,177, +216,166,217,138,216,179,217,138,216,169,216,167,217,132,216,167,217,134,216,170, +217,130,216,167,217,132,217,133,216,180,216,167,216,177,217,131,216,167,216,170, +217,131,216,167,217,132,216,179,217,138,216,167,216,177,216,167,216,170,216,167, +217,132,217,133,217,131,216,170,217,136,216,168,216,169,216,167,217,132,216,179, +216,185,217,136,216,175,217,138,216,169,216,167,216,173,216,181,216,167,216,166, +217,138,216,167,216,170,216,167,217,132,216,185,216,167,217,132,217,133,217,138, +216,169,216,167,217,132,216,181,217,136,216,170,217,138,216,167,216,170,216,167, +217,132,216,167,217,134,216,170,216,177,217,134,216,170,216,167,217,132,216,170, +216,181,216,167,217,133,217,138,217,133,216,167,217,132,216,165,216,179,217,132, +216,167,217,133,217,138,216,167,217,132,217,133,216,180,216,167,216,177,217,131, +216,169,216,167,217,132,217,133,216,177,216,166,217,138,216,167,216,170,114,111, +98,111,116,115,34,32,99,111,110,116,101,110,116,61,34,60,100,105,118,32,105,100, +61,34,102,111,111,116,101,114,34,62,116,104,101,32,85,110,105,116,101,100,32,83, +116,97,116,101,115,60,105,109,103,32,115,114,99,61,34,104,116,116,112,58,47,47, +46,106,112,103,124,114,105,103,104,116,124,116,104,117,109,98,124,46,106,115,34, +62,60,47,115,99,114,105,112,116,62,13,10,60,108,111,99,97,116,105,111,110,46,112 +,114,111,116,111,99,111,108,102,114,97,109,101,98,111,114,100,101,114,61,34,48, +34,32,115,34,32,47,62,10,60,109,101,116,97,32,110,97,109,101,61,34,60,47,97,62, +60,47,100,105,118,62,60,47,100,105,118,62,60,102,111,110,116,45,119,101,105,103, +104,116,58,98,111,108,100,59,38,113,117,111,116,59,32,97,110,100,32,38,113,117, +111,116,59,100,101,112,101,110,100,105,110,103,32,111,110,32,116,104,101,32,109, +97,114,103,105,110,58,48,59,112,97,100,100,105,110,103,58,34,32,114,101,108,61, +34,110,111,102,111,108,108,111,119,34,32,80,114,101,115,105,100,101,110,116,32, +111,102,32,116,104,101,32,116,119,101,110,116,105,101,116,104,32,99,101,110,116, +117,114,121,101,118,105,115,105,111,110,62,10,32,32,60,47,112,97,103,101,73,110, +116,101,114,110,101,116,32,69,120,112,108,111,114,101,114,97,46,97,115,121,110, +99,32,61,32,116,114,117,101,59,13,10,105,110,102,111,114,109,97,116,105,111,110, +32,97,98,111,117,116,60,100,105,118,32,105,100,61,34,104,101,97,100,101,114,34, +62,34,32,97,99,116,105,111,110,61,34,104,116,116,112,58,47,47,60,97,32,104,114, +101,102,61,34,104,116,116,112,115,58,47,47,60,100,105,118,32,105,100,61,34,99, +111,110,116,101,110,116,34,60,47,100,105,118,62,13,10,60,47,100,105,118,62,13,10 +,60,100,101,114,105,118,101,100,32,102,114,111,109,32,116,104,101,32,60,105,109, +103,32,115,114,99,61,39,104,116,116,112,58,47,47,97,99,99,111,114,100,105,110, +103,32,116,111,32,116,104,101,32,10,60,47,98,111,100,121,62,10,60,47,104,116,109 +,108,62,10,115,116,121,108,101,61,34,102,111,110,116,45,115,105,122,101,58,115, +99,114,105,112,116,32,108,97,110,103,117,97,103,101,61,34,65,114,105,97,108,44, +32,72,101,108,118,101,116,105,99,97,44,60,47,97,62,60,115,112,97,110,32,99,108, +97,115,115,61,34,60,47,115,99,114,105,112,116,62,60,115,99,114,105,112,116,32, +112,111,108,105,116,105,99,97,108,32,112,97,114,116,105,101,115,116,100,62,60,47 +,116,114,62,60,47,116,97,98,108,101,62,60,104,114,101,102,61,34,104,116,116,112, +58,47,47,119,119,119,46,105,110,116,101,114,112,114,101,116,97,116,105,111,110, +32,111,102,114,101,108,61,34,115,116,121,108,101,115,104,101,101,116,34,32,100, +111,99,117,109,101,110,116,46,119,114,105,116,101,40,39,60,99,104,97,114,115,101 +,116,61,34,117,116,102,45,56,34,62,10,98,101,103,105,110,110,105,110,103,32,111, +102,32,116,104,101,32,114,101,118,101,97,108,101,100,32,116,104,97,116,32,116, +104,101,116,101,108,101,118,105,115,105,111,110,32,115,101,114,105,101,115,34,32 +,114,101,108,61,34,110,111,102,111,108,108,111,119,34,62,32,116,97,114,103,101, +116,61,34,95,98,108,97,110,107,34,62,99,108,97,105,109,105,110,103,32,116,104,97 +,116,32,116,104,101,104,116,116,112,37,51,65,37,50,70,37,50,70,119,119,119,46, +109,97,110,105,102,101,115,116,97,116,105,111,110,115,32,111,102,80,114,105,109, +101,32,77,105,110,105,115,116,101,114,32,111,102,105,110,102,108,117,101,110,99, +101,100,32,98,121,32,116,104,101,99,108,97,115,115,61,34,99,108,101,97,114,102, +105,120,34,62,47,100,105,118,62,13,10,60,47,100,105,118,62,13,10,13,10,116,104, +114,101,101,45,100,105,109,101,110,115,105,111,110,97,108,67,104,117,114,99,104, +32,111,102,32,69,110,103,108,97,110,100,111,102,32,78,111,114,116,104,32,67,97, +114,111,108,105,110,97,115,113,117,97,114,101,32,107,105,108,111,109,101,116,114 +,101,115,46,97,100,100,69,118,101,110,116,76,105,115,116,101,110,101,114,100,105 +,115,116,105,110,99,116,32,102,114,111,109,32,116,104,101,99,111,109,109,111,110 +,108,121,32,107,110,111,119,110,32,97,115,80,104,111,110,101,116,105,99,32,65, +108,112,104,97,98,101,116,100,101,99,108,97,114,101,100,32,116,104,97,116,32,116 +,104,101,99,111,110,116,114,111,108,108,101,100,32,98,121,32,116,104,101,66,101, +110,106,97,109,105,110,32,70,114,97,110,107,108,105,110,114,111,108,101,45,112, +108,97,121,105,110,103,32,103,97,109,101,116,104,101,32,85,110,105,118,101,114, +115,105,116,121,32,111,102,105,110,32,87,101,115,116,101,114,110,32,69,117,114, +111,112,101,112,101,114,115,111,110,97,108,32,99,111,109,112,117,116,101,114,80, +114,111,106,101,99,116,32,71,117,116,101,110,98,101,114,103,114,101,103,97,114, +100,108,101,115,115,32,111,102,32,116,104,101,104,97,115,32,98,101,101,110,32, +112,114,111,112,111,115,101,100,116,111,103,101,116,104,101,114,32,119,105,116, +104,32,116,104,101,62,60,47,108,105,62,60,108,105,32,99,108,97,115,115,61,34,105 +,110,32,115,111,109,101,32,99,111,117,110,116,114,105,101,115,109,105,110,46,106 +,115,34,62,60,47,115,99,114,105,112,116,62,111,102,32,116,104,101,32,112,111,112 +,117,108,97,116,105,111,110,111,102,102,105,99,105,97,108,32,108,97,110,103,117, +97,103,101,60,105,109,103,32,115,114,99,61,34,105,109,97,103,101,115,47,105,100, +101,110,116,105,102,105,101,100,32,98,121,32,116,104,101,110,97,116,117,114,97, +108,32,114,101,115,111,117,114,99,101,115,99,108,97,115,115,105,102,105,99,97, +116,105,111,110,32,111,102,99,97,110,32,98,101,32,99,111,110,115,105,100,101,114 +,101,100,113,117,97,110,116,117,109,32,109,101,99,104,97,110,105,99,115,78,101, +118,101,114,116,104,101,108,101,115,115,44,32,116,104,101,109,105,108,108,105, +111,110,32,121,101,97,114,115,32,97,103,111,60,47,98,111,100,121,62,13,10,60,47, +104,116,109,108,62,13,206,149,206,187,206,187,206,183,206,189,206,185,206,186, +206,172,10,116,97,107,101,32,97,100,118,97,110,116,97,103,101,32,111,102,97,110, +100,44,32,97,99,99,111,114,100,105,110,103,32,116,111,97,116,116,114,105,98,117, +116,101,100,32,116,111,32,116,104,101,77,105,99,114,111,115,111,102,116,32,87, +105,110,100,111,119,115,116,104,101,32,102,105,114,115,116,32,99,101,110,116,117 +,114,121,117,110,100,101,114,32,116,104,101,32,99,111,110,116,114,111,108,100, +105,118,32,99,108,97,115,115,61,34,104,101,97,100,101,114,115,104,111,114,116, +108,121,32,97,102,116,101,114,32,116,104,101,110,111,116,97,98,108,101,32,101, +120,99,101,112,116,105,111,110,116,101,110,115,32,111,102,32,116,104,111,117,115 +,97,110,100,115,115,101,118,101,114,97,108,32,100,105,102,102,101,114,101,110, +116,97,114,111,117,110,100,32,116,104,101,32,119,111,114,108,100,46,114,101,97, +99,104,105,110,103,32,109,105,108,105,116,97,114,121,105,115,111,108,97,116,101, +100,32,102,114,111,109,32,116,104,101,111,112,112,111,115,105,116,105,111,110,32 +,116,111,32,116,104,101,116,104,101,32,79,108,100,32,84,101,115,116,97,109,101, +110,116,65,102,114,105,99,97,110,32,65,109,101,114,105,99,97,110,115,105,110,115 +,101,114,116,101,100,32,105,110,116,111,32,116,104,101,115,101,112,97,114,97,116 +,101,32,102,114,111,109,32,116,104,101,109,101,116,114,111,112,111,108,105,116, +97,110,32,97,114,101,97,109,97,107,101,115,32,105,116,32,112,111,115,115,105,98, +108,101,97,99,107,110,111,119,108,101,100,103,101,100,32,116,104,97,116,97,114, +103,117,97,98,108,121,32,116,104,101,32,109,111,115,116,116,121,112,101,61,34, +116,101,120,116,47,99,115,115,34,62,10,116,104,101,32,73,110,116,101,114,110,97, +116,105,111,110,97,108,65,99,99,111,114,100,105,110,103,32,116,111,32,116,104, +101,32,112,101,61,34,116,101,120,116,47,99,115,115,34,32,47,62,10,99,111,105,110 +,99,105,100,101,32,119,105,116,104,32,116,104,101,116,119,111,45,116,104,105,114 +,100,115,32,111,102,32,116,104,101,68,117,114,105,110,103,32,116,104,105,115,32, +116,105,109,101,44,100,117,114,105,110,103,32,116,104,101,32,112,101,114,105,111 +,100,97,110,110,111,117,110,99,101,100,32,116,104,97,116,32,104,101,116,104,101, +32,105,110,116,101,114,110,97,116,105,111,110,97,108,97,110,100,32,109,111,114, +101,32,114,101,99,101,110,116,108,121,98,101,108,105,101,118,101,100,32,116,104, +97,116,32,116,104,101,99,111,110,115,99,105,111,117,115,110,101,115,115,32,97, +110,100,102,111,114,109,101,114,108,121,32,107,110,111,119,110,32,97,115,115,117 +,114,114,111,117,110,100,101,100,32,98,121,32,116,104,101,102,105,114,115,116,32 +,97,112,112,101,97,114,101,100,32,105,110,111,99,99,97,115,105,111,110,97,108, +108,121,32,117,115,101,100,112,111,115,105,116,105,111,110,58,97,98,115,111,108, +117,116,101,59,34,32,116,97,114,103,101,116,61,34,95,98,108,97,110,107,34,32,112 +,111,115,105,116,105,111,110,58,114,101,108,97,116,105,118,101,59,116,101,120, +116,45,97,108,105,103,110,58,99,101,110,116,101,114,59,106,97,120,47,108,105,98, +115,47,106,113,117,101,114,121,47,49,46,98,97,99,107,103,114,111,117,110,100,45, +99,111,108,111,114,58,35,116,121,112,101,61,34,97,112,112,108,105,99,97,116,105, +111,110,47,97,110,103,117,97,103,101,34,32,99,111,110,116,101,110,116,61,34,60, +109,101,116,97,32,104,116,116,112,45,101,113,117,105,118,61,34,80,114,105,118,97 +,99,121,32,80,111,108,105,99,121,60,47,97,62,101,40,34,37,51,67,115,99,114,105, +112,116,32,115,114,99,61,39,34,32,116,97,114,103,101,116,61,34,95,98,108,97,110, +107,34,62,79,110,32,116,104,101,32,111,116,104,101,114,32,104,97,110,100,44,46, +106,112,103,124,116,104,117,109,98,124,114,105,103,104,116,124,50,60,47,100,105, +118,62,60,100,105,118,32,99,108,97,115,115,61,34,60,100,105,118,32,115,116,121, +108,101,61,34,102,108,111,97,116,58,110,105,110,101,116,101,101,110,116,104,32, +99,101,110,116,117,114,121,60,47,98,111,100,121,62,13,10,60,47,104,116,109,108, +62,13,10,60,105,109,103,32,115,114,99,61,34,104,116,116,112,58,47,47,115,59,116, +101,120,116,45,97,108,105,103,110,58,99,101,110,116,101,114,102,111,110,116,45, +119,101,105,103,104,116,58,32,98,111,108,100,59,32,65,99,99,111,114,100,105,110, +103,32,116,111,32,116,104,101,32,100,105,102,102,101,114,101,110,99,101,32,98, +101,116,119,101,101,110,34,32,102,114,97,109,101,98,111,114,100,101,114,61,34,48 +,34,32,34,32,115,116,121,108,101,61,34,112,111,115,105,116,105,111,110,58,108, +105,110,107,32,104,114,101,102,61,34,104,116,116,112,58,47,47,104,116,109,108,52 +,47,108,111,111,115,101,46,100,116,100,34,62,10,100,117,114,105,110,103,32,116, +104,105,115,32,112,101,114,105,111,100,60,47,116,100,62,60,47,116,114,62,60,47, +116,97,98,108,101,62,99,108,111,115,101,108,121,32,114,101,108,97,116,101,100,32 +,116,111,102,111,114,32,116,104,101,32,102,105,114,115,116,32,116,105,109,101,59 +,102,111,110,116,45,119,101,105,103,104,116,58,98,111,108,100,59,105,110,112,117 +,116,32,116,121,112,101,61,34,116,101,120,116,34,32,60,115,112,97,110,32,115,116 +,121,108,101,61,34,102,111,110,116,45,111,110,114,101,97,100,121,115,116,97,116, +101,99,104,97,110,103,101,9,60,100,105,118,32,99,108,97,115,115,61,34,99,108,101 +,97,114,100,111,99,117,109,101,110,116,46,108,111,99,97,116,105,111,110,46,32,70 +,111,114,32,101,120,97,109,112,108,101,44,32,116,104,101,32,97,32,119,105,100, +101,32,118,97,114,105,101,116,121,32,111,102,32,60,33,68,79,67,84,89,80,69,32, +104,116,109,108,62,13,10,60,38,110,98,115,112,59,38,110,98,115,112,59,38,110,98, +115,112,59,34,62,60,97,32,104,114,101,102,61,34,104,116,116,112,58,47,47,115,116 +,121,108,101,61,34,102,108,111,97,116,58,108,101,102,116,59,99,111,110,99,101, +114,110,101,100,32,119,105,116,104,32,116,104,101,61,104,116,116,112,37,51,65,37 +,50,70,37,50,70,119,119,119,46,105,110,32,112,111,112,117,108,97,114,32,99,117, +108,116,117,114,101,116,121,112,101,61,34,116,101,120,116,47,99,115,115,34,32,47 +,62,105,116,32,105,115,32,112,111,115,115,105,98,108,101,32,116,111,32,72,97,114 +,118,97,114,100,32,85,110,105,118,101,114,115,105,116,121,116,121,108,101,115, +104,101,101,116,34,32,104,114,101,102,61,34,47,116,104,101,32,109,97,105,110,32, +99,104,97,114,97,99,116,101,114,79,120,102,111,114,100,32,85,110,105,118,101,114 +,115,105,116,121,32,32,110,97,109,101,61,34,107,101,121,119,111,114,100,115,34, +32,99,115,116,121,108,101,61,34,116,101,120,116,45,97,108,105,103,110,58,116,104 +,101,32,85,110,105,116,101,100,32,75,105,110,103,100,111,109,102,101,100,101,114 +,97,108,32,103,111,118,101,114,110,109,101,110,116,60,100,105,118,32,115,116,121 +,108,101,61,34,109,97,114,103,105,110,32,100,101,112,101,110,100,105,110,103,32, +111,110,32,116,104,101,32,100,101,115,99,114,105,112,116,105,111,110,32,111,102, +32,116,104,101,60,100,105,118,32,99,108,97,115,115,61,34,104,101,97,100,101,114, +46,109,105,110,46,106,115,34,62,60,47,115,99,114,105,112,116,62,100,101,115,116, +114,117,99,116,105,111,110,32,111,102,32,116,104,101,115,108,105,103,104,116,108 +,121,32,100,105,102,102,101,114,101,110,116,105,110,32,97,99,99,111,114,100,97, +110,99,101,32,119,105,116,104,116,101,108,101,99,111,109,109,117,110,105,99,97, +116,105,111,110,115,105,110,100,105,99,97,116,101,115,32,116,104,97,116,32,116, +104,101,115,104,111,114,116,108,121,32,116,104,101,114,101,97,102,116,101,114, +101,115,112,101,99,105,97,108,108,121,32,105,110,32,116,104,101,32,69,117,114, +111,112,101,97,110,32,99,111,117,110,116,114,105,101,115,72,111,119,101,118,101, +114,44,32,116,104,101,114,101,32,97,114,101,115,114,99,61,34,104,116,116,112,58, +47,47,115,116,97,116,105,99,115,117,103,103,101,115,116,101,100,32,116,104,97, +116,32,116,104,101,34,32,115,114,99,61,34,104,116,116,112,58,47,47,119,119,119, +46,97,32,108,97,114,103,101,32,110,117,109,98,101,114,32,111,102,32,84,101,108, +101,99,111,109,109,117,110,105,99,97,116,105,111,110,115,34,32,114,101,108,61,34 +,110,111,102,111,108,108,111,119,34,32,116,72,111,108,121,32,82,111,109,97,110, +32,69,109,112,101,114,111,114,97,108,109,111,115,116,32,101,120,99,108,117,115, +105,118,101,108,121,34,32,98,111,114,100,101,114,61,34,48,34,32,97,108,116,61,34 +,83,101,99,114,101,116,97,114,121,32,111,102,32,83,116,97,116,101,99,117,108,109 +,105,110,97,116,105,110,103,32,105,110,32,116,104,101,67,73,65,32,87,111,114,108 +,100,32,70,97,99,116,98,111,111,107,116,104,101,32,109,111,115,116,32,105,109, +112,111,114,116,97,110,116,97,110,110,105,118,101,114,115,97,114,121,32,111,102, +32,116,104,101,115,116,121,108,101,61,34,98,97,99,107,103,114,111,117,110,100,45 +,60,108,105,62,60,101,109,62,60,97,32,104,114,101,102,61,34,47,116,104,101,32,65 +,116,108,97,110,116,105,99,32,79,99,101,97,110,115,116,114,105,99,116,108,121,32 +,115,112,101,97,107,105,110,103,44,115,104,111,114,116,108,121,32,98,101,102,111 +,114,101,32,116,104,101,100,105,102,102,101,114,101,110,116,32,116,121,112,101, +115,32,111,102,116,104,101,32,79,116,116,111,109,97,110,32,69,109,112,105,114, +101,62,60,105,109,103,32,115,114,99,61,34,104,116,116,112,58,47,47,65,110,32,73, +110,116,114,111,100,117,99,116,105,111,110,32,116,111,99,111,110,115,101,113,117 +,101,110,99,101,32,111,102,32,116,104,101,100,101,112,97,114,116,117,114,101,32, +102,114,111,109,32,116,104,101,67,111,110,102,101,100,101,114,97,116,101,32,83, +116,97,116,101,115,105,110,100,105,103,101,110,111,117,115,32,112,101,111,112, +108,101,115,80,114,111,99,101,101,100,105,110,103,115,32,111,102,32,116,104,101, +105,110,102,111,114,109,97,116,105,111,110,32,111,110,32,116,104,101,116,104,101 +,111,114,105,101,115,32,104,97,118,101,32,98,101,101,110,105,110,118,111,108,118 +,101,109,101,110,116,32,105,110,32,116,104,101,100,105,118,105,100,101,100,32, +105,110,116,111,32,116,104,114,101,101,97,100,106,97,99,101,110,116,32,99,111, +117,110,116,114,105,101,115,105,115,32,114,101,115,112,111,110,115,105,98,108, +101,32,102,111,114,100,105,115,115,111,108,117,116,105,111,110,32,111,102,32,116 +,104,101,99,111,108,108,97,98,111,114,97,116,105,111,110,32,119,105,116,104,119, +105,100,101,108,121,32,114,101,103,97,114,100,101,100,32,97,115,104,105,115,32, +99,111,110,116,101,109,112,111,114,97,114,105,101,115,102,111,117,110,100,105, +110,103,32,109,101,109,98,101,114,32,111,102,68,111,109,105,110,105,99,97,110,32 +,82,101,112,117,98,108,105,99,103,101,110,101,114,97,108,108,121,32,97,99,99,101 +,112,116,101,100,116,104,101,32,112,111,115,115,105,98,105,108,105,116,121,32, +111,102,97,114,101,32,97,108,115,111,32,97,118,97,105,108,97,98,108,101,117,110, +100,101,114,32,99,111,110,115,116,114,117,99,116,105,111,110,114,101,115,116,111 +,114,97,116,105,111,110,32,111,102,32,116,104,101,116,104,101,32,103,101,110,101 +,114,97,108,32,112,117,98,108,105,99,105,115,32,97,108,109,111,115,116,32,101, +110,116,105,114,101,108,121,112,97,115,115,101,115,32,116,104,114,111,117,103, +104,32,116,104,101,104,97,115,32,98,101,101,110,32,115,117,103,103,101,115,116, +101,100,99,111,109,112,117,116,101,114,32,97,110,100,32,118,105,100,101,111,71, +101,114,109,97,110,105,99,32,108,97,110,103,117,97,103,101,115,32,97,99,99,111, +114,100,105,110,103,32,116,111,32,116,104,101,32,100,105,102,102,101,114,101,110 +,116,32,102,114,111,109,32,116,104,101,115,104,111,114,116,108,121,32,97,102,116 +,101,114,119,97,114,100,115,104,114,101,102,61,34,104,116,116,112,115,58,47,47, +119,119,119,46,114,101,99,101,110,116,32,100,101,118,101,108,111,112,109,101,110 +,116,66,111,97,114,100,32,111,102,32,68,105,114,101,99,116,111,114,115,60,100, +105,118,32,99,108,97,115,115,61,34,115,101,97,114,99,104,124,32,60,97,32,104,114 +,101,102,61,34,104,116,116,112,58,47,47,73,110,32,112,97,114,116,105,99,117,108, +97,114,44,32,116,104,101,77,117,108,116,105,112,108,101,32,102,111,111,116,110, +111,116,101,115,111,114,32,111,116,104,101,114,32,115,117,98,115,116,97,110,99, +101,116,104,111,117,115,97,110,100,115,32,111,102,32,121,101,97,114,115,116,114, +97,110,115,108,97,116,105,111,110,32,111,102,32,116,104,101,60,47,100,105,118,62 +,13,10,60,47,100,105,118,62,13,10,13,10,60,97,32,104,114,101,102,61,34,105,110, +100,101,120,46,112,104,112,119,97,115,32,101,115,116,97,98,108,105,115,104,101, +100,32,105,110,109,105,110,46,106,115,34,62,60,47,115,99,114,105,112,116,62,10, +112,97,114,116,105,99,105,112,97,116,101,32,105,110,32,116,104,101,97,32,115,116 +,114,111,110,103,32,105,110,102,108,117,101,110,99,101,115,116,121,108,101,61,34 +,109,97,114,103,105,110,45,116,111,112,58,114,101,112,114,101,115,101,110,116, +101,100,32,98,121,32,116,104,101,103,114,97,100,117,97,116,101,100,32,102,114, +111,109,32,116,104,101,84,114,97,100,105,116,105,111,110,97,108,108,121,44,32, +116,104,101,69,108,101,109,101,110,116,40,34,115,99,114,105,112,116,34,41,59,72, +111,119,101,118,101,114,44,32,115,105,110,99,101,32,116,104,101,47,100,105,118, +62,10,60,47,100,105,118,62,10,60,100,105,118,32,108,101,102,116,59,32,109,97,114 +,103,105,110,45,108,101,102,116,58,112,114,111,116,101,99,116,105,111,110,32,97, +103,97,105,110,115,116,48,59,32,118,101,114,116,105,99,97,108,45,97,108,105,103, +110,58,85,110,102,111,114,116,117,110,97,116,101,108,121,44,32,116,104,101,116, +121,112,101,61,34,105,109,97,103,101,47,120,45,105,99,111,110,47,100,105,118,62, +10,60,100,105,118,32,99,108,97,115,115,61,34,32,99,108,97,115,115,61,34,99,108, +101,97,114,102,105,120,34,62,60,100,105,118,32,99,108,97,115,115,61,34,102,111, +111,116,101,114,9,9,60,47,100,105,118,62,10,9,9,60,47,100,105,118,62,10,116,104, +101,32,109,111,116,105,111,110,32,112,105,99,116,117,114,101,208,145,209,138,208 +,187,208,179,208,176,209,128,209,129,208,186,208,184,208,177,209,138,208,187,208 +,179,208,176,209,128,209,129,208,186,208,184,208,164,208,181,208,180,208,181,209 +,128,208,176,209,134,208,184,208,184,208,189,208,181,209,129,208,186,208,190,208 +,187,209,140,208,186,208,190,209,129,208,190,208,190,208,177,209,137,208,181,208 +,189,208,184,208,181,209,129,208,190,208,190,208,177,209,137,208,181,208,189,208 +,184,209,143,208,191,209,128,208,190,208,179,209,128,208,176,208,188,208,188,209 +,139,208,158,209,130,208,191,209,128,208,176,208,178,208,184,209,130,209,140,208 +,177,208,181,209,129,208,191,208,187,208,176,209,130,208,189,208,190,208,188,208 +,176,209,130,208,181,209,128,208,184,208,176,208,187,209,139,208,191,208,190,208 +,183,208,178,208,190,208,187,209,143,208,181,209,130,208,191,208,190,209,129,208 +,187,208,181,208,180,208,189,208,184,208,181,209,128,208,176,208,183,208,187,208 +,184,209,135,208,189,209,139,209,133,208,191,209,128,208,190,208,180,209,131,208 +,186,209,134,208,184,208,184,208,191,209,128,208,190,208,179,209,128,208,176,208 +,188,208,188,208,176,208,191,208,190,208,187,208,189,208,190,209,129,209,130,209 +,140,209,142,208,189,208,176,209,133,208,190,208,180,208,184,209,130,209,129,209 +,143,208,184,208,183,208,177,209,128,208,176,208,189,208,189,208,190,208,181,208 +,189,208,176,209,129,208,181,208,187,208,181,208,189,208,184,209,143,208,184,208 +,183,208,188,208,181,208,189,208,181,208,189,208,184,209,143,208,186,208,176,209 +,130,208,181,208,179,208,190,209,128,208,184,208,184,208,144,208,187,208,181,208 +,186,209,129,208,176,208,189,208,180,209,128,224,164,166,224,165,141,224,164,181 +,224,164,190,224,164,176,224,164,190,224,164,174,224,165,136,224,164,168,224,165 +,129,224,164,133,224,164,178,224,164,170,224,165,141,224,164,176,224,164,166,224 +,164,190,224,164,168,224,164,173,224,164,190,224,164,176,224,164,164,224,165,128 +,224,164,175,224,164,133,224,164,168,224,165,129,224,164,166,224,165,135,224,164 +,182,224,164,185,224,164,191,224,164,168,224,165,141,224,164,166,224,165,128,224 +,164,135,224,164,130,224,164,161,224,164,191,224,164,175,224,164,190,224,164,166 +,224,164,191,224,164,178,224,165,141,224,164,178,224,165,128,224,164,133,224,164 +,167,224,164,191,224,164,149,224,164,190,224,164,176,224,164,181,224,165,128,224 +,164,161,224,164,191,224,164,175,224,165,139,224,164,154,224,164,191,224,164,159 +,224,165,141,224,164,160,224,165,135,224,164,184,224,164,174,224,164,190,224,164 +,154,224,164,190,224,164,176,224,164,156,224,164,130,224,164,149,224,165,141,224 +,164,182,224,164,168,224,164,166,224,165,129,224,164,168,224,164,191,224,164,175 +,224,164,190,224,164,170,224,165,141,224,164,176,224,164,175,224,165,139,224,164 +,151,224,164,133,224,164,168,224,165,129,224,164,184,224,164,190,224,164,176,224 +,164,145,224,164,168,224,164,178,224,164,190,224,164,135,224,164,168,224,164,170 +,224,164,190,224,164,176,224,165,141,224,164,159,224,165,128,224,164,182,224,164 +,176,224,165,141,224,164,164,224,165,139,224,164,130,224,164,178,224,165,139,224 +,164,149,224,164,184,224,164,173,224,164,190,224,164,171,224,164,188,224,165,141 +,224,164,178,224,165,136,224,164,182,224,164,182,224,164,176,224,165,141,224,164 +,164,224,165,135,224,164,130,224,164,170,224,165,141,224,164,176,224,164,166,224 +,165,135,224,164,182,224,164,170,224,165,141,224,164,178,224,165,135,224,164,175 +,224,164,176,224,164,149,224,165,135,224,164,130,224,164,166,224,165,141,224,164 +,176,224,164,184,224,165,141,224,164,165,224,164,191,224,164,164,224,164,191,224 +,164,137,224,164,164,224,165,141,224,164,170,224,164,190,224,164,166,224,164,137 +,224,164,168,224,165,141,224,164,185,224,165,135,224,164,130,224,164,154,224,164 +,191,224,164,159,224,165,141,224,164,160,224,164,190,224,164,175,224,164,190,224 +,164,164,224,165,141,224,164,176,224,164,190,224,164,156,224,165,141,224,164,175 +,224,164,190,224,164,166,224,164,190,224,164,170,224,165,129,224,164,176,224,164 +,190,224,164,168,224,165,135,224,164,156,224,165,139,224,164,161,224,164,188,224 +,165,135,224,164,130,224,164,133,224,164,168,224,165,129,224,164,181,224,164,190 +,224,164,166,224,164,182,224,165,141,224,164,176,224,165,135,224,164,163,224,165 +,128,224,164,182,224,164,191,224,164,149,224,165,141,224,164,183,224,164,190,224 +,164,184,224,164,176,224,164,149,224,164,190,224,164,176,224,165,128,224,164,184 +,224,164,130,224,164,151,224,165,141,224,164,176,224,164,185,224,164,170,224,164 +,176,224,164,191,224,164,163,224,164,190,224,164,174,224,164,172,224,165,141,224 +,164,176,224,164,190,224,164,130,224,164,161,224,164,172,224,164,154,224,165,141 +,224,164,154,224,165,139,224,164,130,224,164,137,224,164,170,224,164,178,224,164 +,172,224,165,141,224,164,167,224,164,174,224,164,130,224,164,164,224,165,141,224 +,164,176,224,165,128,224,164,184,224,164,130,224,164,170,224,164,176,224,165,141 +,224,164,149,224,164,137,224,164,174,224,165,141,224,164,174,224,165,128,224,164 +,166,224,164,174,224,164,190,224,164,167,224,165,141,224,164,175,224,164,174,224 +,164,184,224,164,185,224,164,190,224,164,175,224,164,164,224,164,190,224,164,182 +,224,164,172,224,165,141,224,164,166,224,165,139,224,164,130,224,164,174,224,165 +,128,224,164,161,224,164,191,224,164,175,224,164,190,224,164,134,224,164,136,224 +,164,170,224,165,128,224,164,143,224,164,178,224,164,174,224,165,139,224,164,172 +,224,164,190,224,164,135,224,164,178,224,164,184,224,164,130,224,164,150,224,165 +,141,224,164,175,224,164,190,224,164,134,224,164,170,224,164,176,224,165,135,224 +,164,182,224,164,168,224,164,133,224,164,168,224,165,129,224,164,172,224,164,130 +,224,164,167,224,164,172,224,164,190,224,164,156,224,164,188,224,164,190,224,164 +,176,224,164,168,224,164,181,224,165,128,224,164,168,224,164,164,224,164,174,224 +,164,170,224,165,141,224,164,176,224,164,174,224,165,129,224,164,150,224,164,170 +,224,165,141,224,164,176,224,164,182,224,165,141,224,164,168,224,164,170,224,164 +,176,224,164,191,224,164,181,224,164,190,224,164,176,224,164,168,224,165,129,224 +,164,149,224,164,184,224,164,190,224,164,168,224,164,184,224,164,174,224,164,176 +,224,165,141,224,164,165,224,164,168,224,164,134,224,164,175,224,165,139,224,164 +,156,224,164,191,224,164,164,224,164,184,224,165,139,224,164,174,224,164,181,224 +,164,190,224,164,176,216,167,217,132,217,133,216,180,216,167,216,177,217,131,216 +,167,216,170,216,167,217,132,217,133,217,134,216,170,216,175,217,138,216,167,216 +,170,216,167,217,132,217,131,217,133,216,168,217,138,217,136,216,170,216,177,216 +,167,217,132,217,133,216,180,216,167,217,135,216,175,216,167,216,170,216,185,216 +,175,216,175,216,167,217,132,216,178,217,136,216,167,216,177,216,185,216,175,216 +,175,216,167,217,132,216,177,216,175,217,136,216,175,216,167,217,132,216,165,216 +,179,217,132,216,167,217,133,217,138,216,169,216,167,217,132,217,129,217,136,216 +,170,217,136,216,180,217,136,216,168,216,167,217,132,217,133,216,179,216,167,216 +,168,217,130,216,167,216,170,216,167,217,132,217,133,216,185,217,132,217,136,217 +,133,216,167,216,170,216,167,217,132,217,133,216,179,217,132,216,179,217,132,216 +,167,216,170,216,167,217,132,216,172,216,177,216,167,217,129,217,138,217,131,216 +,179,216,167,217,132,216,167,216,179,217,132,216,167,217,133,217,138,216,169,216 +,167,217,132,216,167,216,170,216,181,216,167,217,132,216,167,216,170,107,101,121 +,119,111,114,100,115,34,32,99,111,110,116,101,110,116,61,34,119,51,46,111,114, +103,47,49,57,57,57,47,120,104,116,109,108,34,62,60,97,32,116,97,114,103,101,116, +61,34,95,98,108,97,110,107,34,32,116,101,120,116,47,104,116,109,108,59,32,99,104 +,97,114,115,101,116,61,34,32,116,97,114,103,101,116,61,34,95,98,108,97,110,107, +34,62,60,116,97,98,108,101,32,99,101,108,108,112,97,100,100,105,110,103,61,34,97 +,117,116,111,99,111,109,112,108,101,116,101,61,34,111,102,102,34,32,116,101,120, +116,45,97,108,105,103,110,58,32,99,101,110,116,101,114,59,116,111,32,108,97,115, +116,32,118,101,114,115,105,111,110,32,98,121,32,98,97,99,107,103,114,111,117,110 +,100,45,99,111,108,111,114,58,32,35,34,32,104,114,101,102,61,34,104,116,116,112, +58,47,47,119,119,119,46,47,100,105,118,62,60,47,100,105,118,62,60,100,105,118,32 +,105,100,61,60,97,32,104,114,101,102,61,34,35,34,32,99,108,97,115,115,61,34,34, +62,60,105,109,103,32,115,114,99,61,34,104,116,116,112,58,47,47,99,114,105,112, +116,34,32,115,114,99,61,34,104,116,116,112,58,47,47,10,60,115,99,114,105,112,116 +,32,108,97,110,103,117,97,103,101,61,34,47,47,69,78,34,32,34,104,116,116,112,58, +47,47,119,119,119,46,119,101,110,99,111,100,101,85,82,73,67,111,109,112,111,110, +101,110,116,40,34,32,104,114,101,102,61,34,106,97,118,97,115,99,114,105,112,116, +58,60,100,105,118,32,99,108,97,115,115,61,34,99,111,110,116,101,110,116,100,111, +99,117,109,101,110,116,46,119,114,105,116,101,40,39,60,115,99,112,111,115,105, +116,105,111,110,58,32,97,98,115,111,108,117,116,101,59,115,99,114,105,112,116,32 +,115,114,99,61,34,104,116,116,112,58,47,47,32,115,116,121,108,101,61,34,109,97, +114,103,105,110,45,116,111,112,58,46,109,105,110,46,106,115,34,62,60,47,115,99, +114,105,112,116,62,10,60,47,100,105,118,62,10,60,100,105,118,32,99,108,97,115, +115,61,34,119,51,46,111,114,103,47,49,57,57,57,47,120,104,116,109,108,34,32,10, +13,10,60,47,98,111,100,121,62,13,10,60,47,104,116,109,108,62,100,105,115,116,105 +,110,99,116,105,111,110,32,98,101,116,119,101,101,110,47,34,32,116,97,114,103, +101,116,61,34,95,98,108,97,110,107,34,62,60,108,105,110,107,32,104,114,101,102, +61,34,104,116,116,112,58,47,47,101,110,99,111,100,105,110,103,61,34,117,116,102, +45,56,34,63,62,10,119,46,97,100,100,69,118,101,110,116,76,105,115,116,101,110, +101,114,63,97,99,116,105,111,110,61,34,104,116,116,112,58,47,47,119,119,119,46, +105,99,111,110,34,32,104,114,101,102,61,34,104,116,116,112,58,47,47,32,115,116, +121,108,101,61,34,98,97,99,107,103,114,111,117,110,100,58,116,121,112,101,61,34, +116,101,120,116,47,99,115,115,34,32,47,62,10,109,101,116,97,32,112,114,111,112, +101,114,116,121,61,34,111,103,58,116,60,105,110,112,117,116,32,116,121,112,101, +61,34,116,101,120,116,34,32,32,115,116,121,108,101,61,34,116,101,120,116,45,97, +108,105,103,110,58,116,104,101,32,100,101,118,101,108,111,112,109,101,110,116,32 +,111,102,32,116,121,108,101,115,104,101,101,116,34,32,116,121,112,101,61,34,116, +101,104,116,109,108,59,32,99,104,97,114,115,101,116,61,117,116,102,45,56,105,115 +,32,99,111,110,115,105,100,101,114,101,100,32,116,111,32,98,101,116,97,98,108, +101,32,119,105,100,116,104,61,34,49,48,48,37,34,32,73,110,32,97,100,100,105,116, +105,111,110,32,116,111,32,116,104,101,32,99,111,110,116,114,105,98,117,116,101, +100,32,116,111,32,116,104,101,32,100,105,102,102,101,114,101,110,99,101,115,32, +98,101,116,119,101,101,110,100,101,118,101,108,111,112,109,101,110,116,32,111, +102,32,116,104,101,32,73,116,32,105,115,32,105,109,112,111,114,116,97,110,116,32 +,116,111,32,60,47,115,99,114,105,112,116,62,10,10,60,115,99,114,105,112,116,32, +32,115,116,121,108,101,61,34,102,111,110,116,45,115,105,122,101,58,49,62,60,47, +115,112,97,110,62,60,115,112,97,110,32,105,100,61,103,98,76,105,98,114,97,114, +121,32,111,102,32,67,111,110,103,114,101,115,115,60,105,109,103,32,115,114,99,61 +,34,104,116,116,112,58,47,47,105,109,69,110,103,108,105,115,104,32,116,114,97, +110,115,108,97,116,105,111,110,65,99,97,100,101,109,121,32,111,102,32,83,99,105, +101,110,99,101,115,100,105,118,32,115,116,121,108,101,61,34,100,105,115,112,108, +97,121,58,99,111,110,115,116,114,117,99,116,105,111,110,32,111,102,32,116,104, +101,46,103,101,116,69,108,101,109,101,110,116,66,121,73,100,40,105,100,41,105, +110,32,99,111,110,106,117,110,99,116,105,111,110,32,119,105,116,104,69,108,101, +109,101,110,116,40,39,115,99,114,105,112,116,39,41,59,32,60,109,101,116,97,32, +112,114,111,112,101,114,116,121,61,34,111,103,58,208,145,209,138,208,187,208,179 +,208,176,209,128,209,129,208,186,208,184,10,32,116,121,112,101,61,34,116,101,120 +,116,34,32,110,97,109,101,61,34,62,80,114,105,118,97,99,121,32,80,111,108,105,99 +,121,60,47,97,62,97,100,109,105,110,105,115,116,101,114,101,100,32,98,121,32,116 +,104,101,101,110,97,98,108,101,83,105,110,103,108,101,82,101,113,117,101,115,116 +,115,116,121,108,101,61,38,113,117,111,116,59,109,97,114,103,105,110,58,60,47, +100,105,118,62,60,47,100,105,118,62,60,47,100,105,118,62,60,62,60,105,109,103,32 +,115,114,99,61,34,104,116,116,112,58,47,47,105,32,115,116,121,108,101,61,38,113, +117,111,116,59,102,108,111,97,116,58,114,101,102,101,114,114,101,100,32,116,111, +32,97,115,32,116,104,101,32,116,111,116,97,108,32,112,111,112,117,108,97,116,105 +,111,110,32,111,102,105,110,32,87,97,115,104,105,110,103,116,111,110,44,32,68,46 +,67,46,32,115,116,121,108,101,61,34,98,97,99,107,103,114,111,117,110,100,45,97, +109,111,110,103,32,111,116,104,101,114,32,116,104,105,110,103,115,44,111,114,103 +,97,110,105,122,97,116,105,111,110,32,111,102,32,116,104,101,112,97,114,116,105, +99,105,112,97,116,101,100,32,105,110,32,116,104,101,116,104,101,32,105,110,116, +114,111,100,117,99,116,105,111,110,32,111,102,105,100,101,110,116,105,102,105, +101,100,32,119,105,116,104,32,116,104,101,102,105,99,116,105,111,110,97,108,32, +99,104,97,114,97,99,116,101,114,32,79,120,102,111,114,100,32,85,110,105,118,101, +114,115,105,116,121,32,109,105,115,117,110,100,101,114,115,116,97,110,100,105, +110,103,32,111,102,84,104,101,114,101,32,97,114,101,44,32,104,111,119,101,118, +101,114,44,115,116,121,108,101,115,104,101,101,116,34,32,104,114,101,102,61,34, +47,67,111,108,117,109,98,105,97,32,85,110,105,118,101,114,115,105,116,121,101, +120,112,97,110,100,101,100,32,116,111,32,105,110,99,108,117,100,101,117,115,117, +97,108,108,121,32,114,101,102,101,114,114,101,100,32,116,111,105,110,100,105,99, +97,116,105,110,103,32,116,104,97,116,32,116,104,101,104,97,118,101,32,115,117, +103,103,101,115,116,101,100,32,116,104,97,116,97,102,102,105,108,105,97,116,101, +100,32,119,105,116,104,32,116,104,101,99,111,114,114,101,108,97,116,105,111,110, +32,98,101,116,119,101,101,110,110,117,109,98,101,114,32,111,102,32,100,105,102, +102,101,114,101,110,116,62,60,47,116,100,62,60,47,116,114,62,60,47,116,97,98,108 +,101,62,82,101,112,117,98,108,105,99,32,111,102,32,73,114,101,108,97,110,100,10, +60,47,115,99,114,105,112,116,62,10,60,115,99,114,105,112,116,32,117,110,100,101, +114,32,116,104,101,32,105,110,102,108,117,101,110,99,101,99,111,110,116,114,105, +98,117,116,105,111,110,32,116,111,32,116,104,101,79,102,102,105,99,105,97,108,32 +,119,101,98,115,105,116,101,32,111,102,104,101,97,100,113,117,97,114,116,101,114 +,115,32,111,102,32,116,104,101,99,101,110,116,101,114,101,100,32,97,114,111,117, +110,100,32,116,104,101,105,109,112,108,105,99,97,116,105,111,110,115,32,111,102, +32,116,104,101,104,97,118,101,32,98,101,101,110,32,100,101,118,101,108,111,112, +101,100,70,101,100,101,114,97,108,32,82,101,112,117,98,108,105,99,32,111,102,98, +101,99,97,109,101,32,105,110,99,114,101,97,115,105,110,103,108,121,99,111,110, +116,105,110,117,97,116,105,111,110,32,111,102,32,116,104,101,78,111,116,101,44, +32,104,111,119,101,118,101,114,44,32,116,104,97,116,115,105,109,105,108,97,114, +32,116,111,32,116,104,97,116,32,111,102,32,99,97,112,97,98,105,108,105,116,105, +101,115,32,111,102,32,116,104,101,97,99,99,111,114,100,97,110,99,101,32,119,105, +116,104,32,116,104,101,112,97,114,116,105,99,105,112,97,110,116,115,32,105,110, +32,116,104,101,102,117,114,116,104,101,114,32,100,101,118,101,108,111,112,109, +101,110,116,117,110,100,101,114,32,116,104,101,32,100,105,114,101,99,116,105,111 +,110,105,115,32,111,102,116,101,110,32,99,111,110,115,105,100,101,114,101,100, +104,105,115,32,121,111,117,110,103,101,114,32,98,114,111,116,104,101,114,60,47, +116,100,62,60,47,116,114,62,60,47,116,97,98,108,101,62,60,97,32,104,116,116,112, +45,101,113,117,105,118,61,34,88,45,85,65,45,112,104,121,115,105,99,97,108,32,112 +,114,111,112,101,114,116,105,101,115,111,102,32,66,114,105,116,105,115,104,32,67 +,111,108,117,109,98,105,97,104,97,115,32,98,101,101,110,32,99,114,105,116,105,99 +,105,122,101,100,40,119,105,116,104,32,116,104,101,32,101,120,99,101,112,116,105 +,111,110,113,117,101,115,116,105,111,110,115,32,97,98,111,117,116,32,116,104,101 +,112,97,115,115,105,110,103,32,116,104,114,111,117,103,104,32,116,104,101,48,34, +32,99,101,108,108,112,97,100,100,105,110,103,61,34,48,34,32,116,104,111,117,115, +97,110,100,115,32,111,102,32,112,101,111,112,108,101,114,101,100,105,114,101,99, +116,115,32,104,101,114,101,46,32,70,111,114,104,97,118,101,32,99,104,105,108,100 +,114,101,110,32,117,110,100,101,114,37,51,69,37,51,67,47,115,99,114,105,112,116, +37,51,69,34,41,41,59,60,97,32,104,114,101,102,61,34,104,116,116,112,58,47,47,119 +,119,119,46,60,108,105,62,60,97,32,104,114,101,102,61,34,104,116,116,112,58,47, +47,115,105,116,101,95,110,97,109,101,34,32,99,111,110,116,101,110,116,61,34,116, +101,120,116,45,100,101,99,111,114,97,116,105,111,110,58,110,111,110,101,115,116, +121,108,101,61,34,100,105,115,112,108,97,121,58,32,110,111,110,101,60,109,101, +116,97,32,104,116,116,112,45,101,113,117,105,118,61,34,88,45,110,101,119,32,68, +97,116,101,40,41,46,103,101,116,84,105,109,101,40,41,32,116,121,112,101,61,34, +105,109,97,103,101,47,120,45,105,99,111,110,34,60,47,115,112,97,110,62,60,115, +112,97,110,32,99,108,97,115,115,61,34,108,97,110,103,117,97,103,101,61,34,106,97 +,118,97,115,99,114,105,112,116,119,105,110,100,111,119,46,108,111,99,97,116,105, +111,110,46,104,114,101,102,60,97,32,104,114,101,102,61,34,106,97,118,97,115,99, +114,105,112,116,58,45,45,62,13,10,60,115,99,114,105,112,116,32,116,121,112,101, +61,34,116,60,97,32,104,114,101,102,61,39,104,116,116,112,58,47,47,119,119,119,46 +,104,111,114,116,99,117,116,32,105,99,111,110,34,32,104,114,101,102,61,34,60,47, +100,105,118,62,13,10,60,100,105,118,32,99,108,97,115,115,61,34,60,115,99,114,105 +,112,116,32,115,114,99,61,34,104,116,116,112,58,47,47,34,32,114,101,108,61,34, +115,116,121,108,101,115,104,101,101,116,34,32,116,60,47,100,105,118,62,10,60,115 +,99,114,105,112,116,32,116,121,112,101,61,47,97,62,32,60,97,32,104,114,101,102, +61,34,104,116,116,112,58,47,47,32,97,108,108,111,119,84,114,97,110,115,112,97, +114,101,110,99,121,61,34,88,45,85,65,45,67,111,109,112,97,116,105,98,108,101,34, +32,99,111,110,114,101,108,97,116,105,111,110,115,104,105,112,32,98,101,116,119, +101,101,110,10,60,47,115,99,114,105,112,116,62,13,10,60,115,99,114,105,112,116, +32,60,47,97,62,60,47,108,105,62,60,47,117,108,62,60,47,100,105,118,62,97,115,115 +,111,99,105,97,116,101,100,32,119,105,116,104,32,116,104,101,32,112,114,111,103, +114,97,109,109,105,110,103,32,108,97,110,103,117,97,103,101,60,47,97,62,60,97,32 +,104,114,101,102,61,34,104,116,116,112,58,47,47,60,47,97,62,60,47,108,105,62,60, +108,105,32,99,108,97,115,115,61,34,102,111,114,109,32,97,99,116,105,111,110,61, +34,104,116,116,112,58,47,47,60,100,105,118,32,115,116,121,108,101,61,34,100,105, +115,112,108,97,121,58,116,121,112,101,61,34,116,101,120,116,34,32,110,97,109,101 +,61,34,113,34,60,116,97,98,108,101,32,119,105,100,116,104,61,34,49,48,48,37,34, +32,98,97,99,107,103,114,111,117,110,100,45,112,111,115,105,116,105,111,110,58,34 +,32,98,111,114,100,101,114,61,34,48,34,32,119,105,100,116,104,61,34,114,101,108, +61,34,115,104,111,114,116,99,117,116,32,105,99,111,110,34,32,104,54,62,60,117, +108,62,60,108,105,62,60,97,32,104,114,101,102,61,34,32,32,60,109,101,116,97,32, +104,116,116,112,45,101,113,117,105,118,61,34,99,115,115,34,32,109,101,100,105,97 +,61,34,115,99,114,101,101,110,34,32,114,101,115,112,111,110,115,105,98,108,101, +32,102,111,114,32,116,104,101,32,34,32,116,121,112,101,61,34,97,112,112,108,105, +99,97,116,105,111,110,47,34,32,115,116,121,108,101,61,34,98,97,99,107,103,114, +111,117,110,100,45,104,116,109,108,59,32,99,104,97,114,115,101,116,61,117,116, +102,45,56,34,32,97,108,108,111,119,116,114,97,110,115,112,97,114,101,110,99,121, +61,34,115,116,121,108,101,115,104,101,101,116,34,32,116,121,112,101,61,34,116, +101,13,10,60,109,101,116,97,32,104,116,116,112,45,101,113,117,105,118,61,34,62, +60,47,115,112,97,110,62,60,115,112,97,110,32,99,108,97,115,115,61,34,48,34,32,99 +,101,108,108,115,112,97,99,105,110,103,61,34,48,34,62,59,10,60,47,115,99,114,105 +,112,116,62,10,60,115,99,114,105,112,116,32,115,111,109,101,116,105,109,101,115, +32,99,97,108,108,101,100,32,116,104,101,100,111,101,115,32,110,111,116,32,110, +101,99,101,115,115,97,114,105,108,121,70,111,114,32,109,111,114,101,32,105,110, +102,111,114,109,97,116,105,111,110,97,116,32,116,104,101,32,98,101,103,105,110, +110,105,110,103,32,111,102,32,60,33,68,79,67,84,89,80,69,32,104,116,109,108,62, +60,104,116,109,108,112,97,114,116,105,99,117,108,97,114,108,121,32,105,110,32, +116,104,101,32,116,121,112,101,61,34,104,105,100,100,101,110,34,32,110,97,109, +101,61,34,106,97,118,97,115,99,114,105,112,116,58,118,111,105,100,40,48,41,59,34 +,101,102,102,101,99,116,105,118,101,110,101,115,115,32,111,102,32,116,104,101,32 +,97,117,116,111,99,111,109,112,108,101,116,101,61,34,111,102,102,34,32,103,101, +110,101,114,97,108,108,121,32,99,111,110,115,105,100,101,114,101,100,62,60,105, +110,112,117,116,32,116,121,112,101,61,34,116,101,120,116,34,32,34,62,60,47,115, +99,114,105,112,116,62,13,10,60,115,99,114,105,112,116,116,104,114,111,117,103, +104,111,117,116,32,116,104,101,32,119,111,114,108,100,99,111,109,109,111,110,32, +109,105,115,99,111,110,99,101,112,116,105,111,110,97,115,115,111,99,105,97,116, +105,111,110,32,119,105,116,104,32,116,104,101,60,47,100,105,118,62,10,60,47,100, +105,118,62,10,60,100,105,118,32,99,100,117,114,105,110,103,32,104,105,115,32,108 +,105,102,101,116,105,109,101,44,99,111,114,114,101,115,112,111,110,100,105,110, +103,32,116,111,32,116,104,101,116,121,112,101,61,34,105,109,97,103,101,47,120,45 +,105,99,111,110,34,32,97,110,32,105,110,99,114,101,97,115,105,110,103,32,110,117 +,109,98,101,114,100,105,112,108,111,109,97,116,105,99,32,114,101,108,97,116,105, +111,110,115,97,114,101,32,111,102,116,101,110,32,99,111,110,115,105,100,101,114, +101,100,109,101,116,97,32,99,104,97,114,115,101,116,61,34,117,116,102,45,56,34, +32,60,105,110,112,117,116,32,116,121,112,101,61,34,116,101,120,116,34,32,101,120 +,97,109,112,108,101,115,32,105,110,99,108,117,100,101,32,116,104,101,34,62,60, +105,109,103,32,115,114,99,61,34,104,116,116,112,58,47,47,105,112,97,114,116,105, +99,105,112,97,116,105,111,110,32,105,110,32,116,104,101,116,104,101,32,101,115, +116,97,98,108,105,115,104,109,101,110,116,32,111,102,10,60,47,100,105,118,62,10, +60,100,105,118,32,99,108,97,115,115,61,34,38,97,109,112,59,110,98,115,112,59,38, +97,109,112,59,110,98,115,112,59,116,111,32,100,101,116,101,114,109,105,110,101, +32,119,104,101,116,104,101,114,113,117,105,116,101,32,100,105,102,102,101,114, +101,110,116,32,102,114,111,109,109,97,114,107,101,100,32,116,104,101,32,98,101, +103,105,110,110,105,110,103,100,105,115,116,97,110,99,101,32,98,101,116,119,101, +101,110,32,116,104,101,99,111,110,116,114,105,98,117,116,105,111,110,115,32,116, +111,32,116,104,101,99,111,110,102,108,105,99,116,32,98,101,116,119,101,101,110, +32,116,104,101,119,105,100,101,108,121,32,99,111,110,115,105,100,101,114,101,100 +,32,116,111,119,97,115,32,111,110,101,32,111,102,32,116,104,101,32,102,105,114, +115,116,119,105,116,104,32,118,97,114,121,105,110,103,32,100,101,103,114,101,101 +,115,104,97,118,101,32,115,112,101,99,117,108,97,116,101,100,32,116,104,97,116, +40,100,111,99,117,109,101,110,116,46,103,101,116,69,108,101,109,101,110,116,112, +97,114,116,105,99,105,112,97,116,105,110,103,32,105,110,32,116,104,101,111,114, +105,103,105,110,97,108,108,121,32,100,101,118,101,108,111,112,101,100,101,116,97 +,32,99,104,97,114,115,101,116,61,34,117,116,102,45,56,34,62,32,116,121,112,101, +61,34,116,101,120,116,47,99,115,115,34,32,47,62,10,105,110,116,101,114,99,104,97 +,110,103,101,97,98,108,121,32,119,105,116,104,109,111,114,101,32,99,108,111,115, +101,108,121,32,114,101,108,97,116,101,100,115,111,99,105,97,108,32,97,110,100,32 +,112,111,108,105,116,105,99,97,108,116,104,97,116,32,119,111,117,108,100,32,111, +116,104,101,114,119,105,115,101,112,101,114,112,101,110,100,105,99,117,108,97, +114,32,116,111,32,116,104,101,115,116,121,108,101,32,116,121,112,101,61,34,116, +101,120,116,47,99,115,115,116,121,112,101,61,34,115,117,98,109,105,116,34,32,110 +,97,109,101,61,34,102,97,109,105,108,105,101,115,32,114,101,115,105,100,105,110, +103,32,105,110,100,101,118,101,108,111,112,105,110,103,32,99,111,117,110,116,114 +,105,101,115,99,111,109,112,117,116,101,114,32,112,114,111,103,114,97,109,109, +105,110,103,101,99,111,110,111,109,105,99,32,100,101,118,101,108,111,112,109,101 +,110,116,100,101,116,101,114,109,105,110,97,116,105,111,110,32,111,102,32,116, +104,101,102,111,114,32,109,111,114,101,32,105,110,102,111,114,109,97,116,105,111 +,110,111,110,32,115,101,118,101,114,97,108,32,111,99,99,97,115,105,111,110,115, +112,111,114,116,117,103,117,195,170,115,32,40,69,117,114,111,112,101,117,41,208, +163,208,186,209,128,208,176,209,151,208,189,209,129,209,140,208,186,208,176,209, +131,208,186,209,128,208,176,209,151,208,189,209,129,209,140,208,186,208,176,208, +160,208,190,209,129,209,129,208,184,208,185,209,129,208,186,208,190,208,185,208, +188,208,176,209,130,208,181,209,128,208,184,208,176,208,187,208,190,208,178,208, +184,208,189,209,132,208,190,209,128,208,188,208,176,209,134,208,184,208,184,209, +131,208,191,209,128,208,176,208,178,208,187,208,181,208,189,208,184,209,143,208, +189,208,181,208,190,208,177,209,133,208,190,208,180,208,184,208,188,208,190,208, +184,208,189,209,132,208,190,209,128,208,188,208,176,209,134,208,184,209,143,208, +152,208,189,209,132,208,190,209,128,208,188,208,176,209,134,208,184,209,143,208, +160,208,181,209,129,208,191,209,131,208,177,208,187,208,184,208,186,208,184,208, +186,208,190,208,187,208,184,209,135,208,181,209,129,209,130,208,178,208,190,208, +184,208,189,209,132,208,190,209,128,208,188,208,176,209,134,208,184,209,142,209, +130,208,181,209,128,209,128,208,184,209,130,208,190,209,128,208,184,208,184,208, +180,208,190,209,129,209,130,208,176,209,130,208,190,209,135,208,189,208,190,216, +167,217,132,217,133,216,170,217,136,216,167,216,172,216,175,217,136,217,134,216, +167,217,132,216,167,216,180,216,170,216,177,216,167,217,131,216,167,216,170,216, +167,217,132,216,167,217,130,216,170,216,177,216,167,216,173,216,167,216,170,104, +116,109,108,59,32,99,104,97,114,115,101,116,61,85,84,70,45,56,34,32,115,101,116, +84,105,109,101,111,117,116,40,102,117,110,99,116,105,111,110,40,41,100,105,115, +112,108,97,121,58,105,110,108,105,110,101,45,98,108,111,99,107,59,60,105,110,112 +,117,116,32,116,121,112,101,61,34,115,117,98,109,105,116,34,32,116,121,112,101, +32,61,32,39,116,101,120,116,47,106,97,118,97,115,99,114,105,60,105,109,103,32, +115,114,99,61,34,104,116,116,112,58,47,47,119,119,119,46,34,32,34,104,116,116, +112,58,47,47,119,119,119,46,119,51,46,111,114,103,47,115,104,111,114,116,99,117, +116,32,105,99,111,110,34,32,104,114,101,102,61,34,34,32,97,117,116,111,99,111, +109,112,108,101,116,101,61,34,111,102,102,34,32,60,47,97,62,60,47,100,105,118,62 +,60,100,105,118,32,99,108,97,115,115,61,60,47,97,62,60,47,108,105,62,10,60,108, +105,32,99,108,97,115,115,61,34,99,115,115,34,32,116,121,112,101,61,34,116,101, +120,116,47,99,115,115,34,32,60,102,111,114,109,32,97,99,116,105,111,110,61,34, +104,116,116,112,58,47,47,120,116,47,99,115,115,34,32,104,114,101,102,61,34,104, +116,116,112,58,47,47,108,105,110,107,32,114,101,108,61,34,97,108,116,101,114,110 +,97,116,101,34,32,13,10,60,115,99,114,105,112,116,32,116,121,112,101,61,34,116, +101,120,116,47,32,111,110,99,108,105,99,107,61,34,106,97,118,97,115,99,114,105, +112,116,58,40,110,101,119,32,68,97,116,101,41,46,103,101,116,84,105,109,101,40, +41,125,104,101,105,103,104,116,61,34,49,34,32,119,105,100,116,104,61,34,49,34,32 +,80,101,111,112,108,101,39,115,32,82,101,112,117,98,108,105,99,32,111,102,32,32, +60,97,32,104,114,101,102,61,34,104,116,116,112,58,47,47,119,119,119,46,116,101, +120,116,45,100,101,99,111,114,97,116,105,111,110,58,117,110,100,101,114,116,104, +101,32,98,101,103,105,110,110,105,110,103,32,111,102,32,116,104,101,32,60,47,100 +,105,118,62,10,60,47,100,105,118,62,10,60,47,100,105,118,62,10,101,115,116,97,98 +,108,105,115,104,109,101,110,116,32,111,102,32,116,104,101,32,60,47,100,105,118, +62,60,47,100,105,118,62,60,47,100,105,118,62,60,47,100,35,118,105,101,119,112, +111,114,116,123,109,105,110,45,104,101,105,103,104,116,58,10,60,115,99,114,105, +112,116,32,115,114,99,61,34,104,116,116,112,58,47,47,111,112,116,105,111,110,62, +60,111,112,116,105,111,110,32,118,97,108,117,101,61,111,102,116,101,110,32,114, +101,102,101,114,114,101,100,32,116,111,32,97,115,32,47,111,112,116,105,111,110, +62,10,60,111,112,116,105,111,110,32,118,97,108,117,60,33,68,79,67,84,89,80,69,32 +,104,116,109,108,62,10,60,33,45,45,91,73,110,116,101,114,110,97,116,105,111,110, +97,108,32,65,105,114,112,111,114,116,62,10,60,97,32,104,114,101,102,61,34,104, +116,116,112,58,47,47,119,119,119,60,47,97,62,60,97,32,104,114,101,102,61,34,104, +116,116,112,58,47,47,119,224,184,160,224,184,178,224,184,169,224,184,178,224,185 +,132,224,184,151,224,184,162,225,131,165,225,131,144,225,131,160,225,131,151,225 +,131,163,225,131,154,225,131,152,230,173,163,233,171,148,228,184,173,230,150,135 +,32,40,231,185,129,233,171,148,41,224,164,168,224,164,191,224,164,176,224,165, +141,224,164,166,224,165,135,224,164,182,224,164,161,224,164,190,224,164,137,224, +164,168,224,164,178,224,165,139,224,164,161,224,164,149,224,165,141,224,164,183, +224,165,135,224,164,164,224,165,141,224,164,176,224,164,156,224,164,190,224,164, +168,224,164,149,224,164,190,224,164,176,224,165,128,224,164,184,224,164,130,224, +164,172,224,164,130,224,164,167,224,164,191,224,164,164,224,164,184,224,165,141, +224,164,165,224,164,190,224,164,170,224,164,168,224,164,190,224,164,184,224,165, +141,224,164,181,224,165,128,224,164,149,224,164,190,224,164,176,224,164,184,224, +164,130,224,164,184,224,165,141,224,164,149,224,164,176,224,164,163,224,164,184, +224,164,190,224,164,174,224,164,151,224,165,141,224,164,176,224,165,128,224,164, +154,224,164,191,224,164,159,224,165,141,224,164,160,224,165,139,224,164,130,224, +164,181,224,164,191,224,164,156,224,165,141,224,164,158,224,164,190,224,164,168, +224,164,133,224,164,174,224,165,135,224,164,176,224,164,191,224,164,149,224,164, +190,224,164,181,224,164,191,224,164,173,224,164,191,224,164,168,224,165,141,224, +164,168,224,164,151,224,164,190,224,164,161,224,164,191,224,164,175,224,164,190, +224,164,129,224,164,149,224,165,141,224,164,175,224,165,139,224,164,130,224,164, +149,224,164,191,224,164,184,224,165,129,224,164,176,224,164,149,224,165,141,224, +164,183,224,164,190,224,164,170,224,164,185,224,165,129,224,164,129,224,164,154, +224,164,164,224,165,128,224,164,170,224,165,141,224,164,176,224,164,172,224,164, +130,224,164,167,224,164,168,224,164,159,224,164,191,224,164,170,224,165,141,224, +164,170,224,164,163,224,165,128,224,164,149,224,165,141,224,164,176,224,164,191, +224,164,149,224,165,135,224,164,159,224,164,170,224,165,141,224,164,176,224,164, +190,224,164,176,224,164,130,224,164,173,224,164,170,224,165,141,224,164,176,224, +164,190,224,164,170,224,165,141,224,164,164,224,164,174,224,164,190,224,164,178, +224,164,191,224,164,149,224,165,139,224,164,130,224,164,176,224,164,171,224,164, +188,224,165,141,224,164,164,224,164,190,224,164,176,224,164,168,224,164,191,224, +164,176,224,165,141,224,164,174,224,164,190,224,164,163,224,164,178,224,164,191, +224,164,174,224,164,191,224,164,159,224,165,135,224,164,161,100,101,115,99,114, +105,112,116,105,111,110,34,32,99,111,110,116,101,110,116,61,34,100,111,99,117, +109,101,110,116,46,108,111,99,97,116,105,111,110,46,112,114,111,116,46,103,101, +116,69,108,101,109,101,110,116,115,66,121,84,97,103,78,97,109,101,40,60,33,68,79 +,67,84,89,80,69,32,104,116,109,108,62,10,60,104,116,109,108,32,60,109,101,116,97 +,32,99,104,97,114,115,101,116,61,34,117,116,102,45,56,34,62,58,117,114,108,34,32 +,99,111,110,116,101,110,116,61,34,104,116,116,112,58,47,47,46,99,115,115,34,32, +114,101,108,61,34,115,116,121,108,101,115,104,101,101,116,34,115,116,121,108,101 +,32,116,121,112,101,61,34,116,101,120,116,47,99,115,115,34,62,116,121,112,101,61 +,34,116,101,120,116,47,99,115,115,34,32,104,114,101,102,61,34,119,51,46,111,114, +103,47,49,57,57,57,47,120,104,116,109,108,34,32,120,109,108,116,121,112,101,61, +34,116,101,120,116,47,106,97,118,97,115,99,114,105,112,116,34,32,109,101,116,104 +,111,100,61,34,103,101,116,34,32,97,99,116,105,111,110,61,34,108,105,110,107,32, +114,101,108,61,34,115,116,121,108,101,115,104,101,101,116,34,32,32,61,32,100,111 +,99,117,109,101,110,116,46,103,101,116,69,108,101,109,101,110,116,116,121,112, +101,61,34,105,109,97,103,101,47,120,45,105,99,111,110,34,32,47,62,99,101,108,108 +,112,97,100,100,105,110,103,61,34,48,34,32,99,101,108,108,115,112,46,99,115,115, +34,32,116,121,112,101,61,34,116,101,120,116,47,99,115,115,34,32,60,47,97,62,60, +47,108,105,62,60,108,105,62,60,97,32,104,114,101,102,61,34,34,32,119,105,100,116 +,104,61,34,49,34,32,104,101,105,103,104,116,61,34,49,34,34,62,60,97,32,104,114, +101,102,61,34,104,116,116,112,58,47,47,119,119,119,46,115,116,121,108,101,61,34, +100,105,115,112,108,97,121,58,110,111,110,101,59,34,62,97,108,116,101,114,110,97 +,116,101,34,32,116,121,112,101,61,34,97,112,112,108,105,45,47,47,87,51,67,47,47, +68,84,68,32,88,72,84,77,76,32,49,46,48,32,101,108,108,115,112,97,99,105,110,103, +61,34,48,34,32,99,101,108,108,112,97,100,32,116,121,112,101,61,34,104,105,100, +100,101,110,34,32,118,97,108,117,101,61,34,47,97,62,38,110,98,115,112,59,60,115, +112,97,110,32,114,111,108,101,61,34,115,10,60,105,110,112,117,116,32,116,121,112 +,101,61,34,104,105,100,100,101,110,34,32,108,97,110,103,117,97,103,101,61,34,74, +97,118,97,83,99,114,105,112,116,34,32,32,100,111,99,117,109,101,110,116,46,103, +101,116,69,108,101,109,101,110,116,115,66,103,61,34,48,34,32,99,101,108,108,115, +112,97,99,105,110,103,61,34,48,34,32,121,112,101,61,34,116,101,120,116,47,99,115 +,115,34,32,109,101,100,105,97,61,34,116,121,112,101,61,39,116,101,120,116,47,106 +,97,118,97,115,99,114,105,112,116,39,119,105,116,104,32,116,104,101,32,101,120, +99,101,112,116,105,111,110,32,111,102,32,121,112,101,61,34,116,101,120,116,47,99 +,115,115,34,32,114,101,108,61,34,115,116,32,104,101,105,103,104,116,61,34,49,34, +32,119,105,100,116,104,61,34,49,34,32,61,39,43,101,110,99,111,100,101,85,82,73, +67,111,109,112,111,110,101,110,116,40,60,108,105,110,107,32,114,101,108,61,34,97 +,108,116,101,114,110,97,116,101,34,32,10,98,111,100,121,44,32,116,114,44,32,105, +110,112,117,116,44,32,116,101,120,116,109,101,116,97,32,110,97,109,101,61,34,114 +,111,98,111,116,115,34,32,99,111,110,109,101,116,104,111,100,61,34,112,111,115, +116,34,32,97,99,116,105,111,110,61,34,62,10,60,97,32,104,114,101,102,61,34,104, +116,116,112,58,47,47,119,119,119,46,99,115,115,34,32,114,101,108,61,34,115,116, +121,108,101,115,104,101,101,116,34,32,60,47,100,105,118,62,60,47,100,105,118,62, +60,100,105,118,32,99,108,97,115,115,108,97,110,103,117,97,103,101,61,34,106,97, +118,97,115,99,114,105,112,116,34,62,97,114,105,97,45,104,105,100,100,101,110,61, +34,116,114,117,101,34,62,194,183,60,114,105,112,116,34,32,116,121,112,101,61,34, +116,101,120,116,47,106,97,118,97,115,108,61,48,59,125,41,40,41,59,10,40,102,117, +110,99,116,105,111,110,40,41,123,98,97,99,107,103,114,111,117,110,100,45,105,109 +,97,103,101,58,32,117,114,108,40,47,97,62,60,47,108,105,62,60,108,105,62,60,97, +32,104,114,101,102,61,34,104,9,9,60,108,105,62,60,97,32,104,114,101,102,61,34, +104,116,116,112,58,47,47,97,116,111,114,34,32,97,114,105,97,45,104,105,100,100, +101,110,61,34,116,114,117,62,32,60,97,32,104,114,101,102,61,34,104,116,116,112, +58,47,47,119,119,119,46,108,97,110,103,117,97,103,101,61,34,106,97,118,97,115,99 +,114,105,112,116,34,32,47,111,112,116,105,111,110,62,10,60,111,112,116,105,111, +110,32,118,97,108,117,101,47,100,105,118,62,60,47,100,105,118,62,60,100,105,118, +32,99,108,97,115,115,61,114,97,116,111,114,34,32,97,114,105,97,45,104,105,100, +100,101,110,61,34,116,114,101,61,40,110,101,119,32,68,97,116,101,41,46,103,101, +116,84,105,109,101,40,41,112,111,114,116,117,103,117,195,170,115,32,40,100,111, +32,66,114,97,115,105,108,41,208,190,209,128,208,179,208,176,208,189,208,184,208, +183,208,176,209,134,208,184,208,184,208,178,208,190,208,183,208,188,208,190,208, +182,208,189,208,190,209,129,209,130,209,140,208,190,208,177,209,128,208,176,208, +183,208,190,208,178,208,176,208,189,208,184,209,143,209,128,208,181,208,179,208, +184,209,129,209,130,209,128,208,176,209,134,208,184,208,184,208,178,208,190,208, +183,208,188,208,190,208,182,208,189,208,190,209,129,209,130,208,184,208,190,208, +177,209,143,208,183,208,176,209,130,208,181,208,187,209,140,208,189,208,176,60, +33,68,79,67,84,89,80,69,32,104,116,109,108,32,80,85,66,76,73,67,32,34,110,116,45 +,84,121,112,101,34,32,99,111,110,116,101,110,116,61,34,116,101,120,116,47,60,109 +,101,116,97,32,104,116,116,112,45,101,113,117,105,118,61,34,67,111,110,116,101, +114,97,110,115,105,116,105,111,110,97,108,47,47,69,78,34,32,34,104,116,116,112, +58,60,104,116,109,108,32,120,109,108,110,115,61,34,104,116,116,112,58,47,47,119, +119,119,45,47,47,87,51,67,47,47,68,84,68,32,88,72,84,77,76,32,49,46,48,32,84,68, +84,68,47,120,104,116,109,108,49,45,116,114,97,110,115,105,116,105,111,110,97,108 +,47,47,119,119,119,46,119,51,46,111,114,103,47,84,82,47,120,104,116,109,108,49, +47,112,101,32,61,32,39,116,101,120,116,47,106,97,118,97,115,99,114,105,112,116, +39,59,60,109,101,116,97,32,110,97,109,101,61,34,100,101,115,99,114,105,112,116, +105,111,110,112,97,114,101,110,116,78,111,100,101,46,105,110,115,101,114,116,66, +101,102,111,114,101,60,105,110,112,117,116,32,116,121,112,101,61,34,104,105,100, +100,101,110,34,32,110,97,106,115,34,32,116,121,112,101,61,34,116,101,120,116,47, +106,97,118,97,115,99,114,105,40,100,111,99,117,109,101,110,116,41,46,114,101,97, +100,121,40,102,117,110,99,116,105,115,99,114,105,112,116,32,116,121,112,101,61, +34,116,101,120,116,47,106,97,118,97,115,105,109,97,103,101,34,32,99,111,110,116, +101,110,116,61,34,104,116,116,112,58,47,47,85,65,45,67,111,109,112,97,116,105,98 +,108,101,34,32,99,111,110,116,101,110,116,61,116,109,108,59,32,99,104,97,114,115 +,101,116,61,117,116,102,45,56,34,32,47,62,10,108,105,110,107,32,114,101,108,61, +34,115,104,111,114,116,99,117,116,32,105,99,111,110,60,108,105,110,107,32,114, +101,108,61,34,115,116,121,108,101,115,104,101,101,116,34,32,60,47,115,99,114,105 +,112,116,62,10,60,115,99,114,105,112,116,32,116,121,112,101,61,61,32,100,111,99, +117,109,101,110,116,46,99,114,101,97,116,101,69,108,101,109,101,110,60,97,32,116 +,97,114,103,101,116,61,34,95,98,108,97,110,107,34,32,104,114,101,102,61,32,100, +111,99,117,109,101,110,116,46,103,101,116,69,108,101,109,101,110,116,115,66,105, +110,112,117,116,32,116,121,112,101,61,34,116,101,120,116,34,32,110,97,109,101,61 +,97,46,116,121,112,101,32,61,32,39,116,101,120,116,47,106,97,118,97,115,99,114, +105,110,112,117,116,32,116,121,112,101,61,34,104,105,100,100,101,110,34,32,110, +97,109,101,104,116,109,108,59,32,99,104,97,114,115,101,116,61,117,116,102,45,56, +34,32,47,62,100,116,100,34,62,10,60,104,116,109,108,32,120,109,108,110,115,61,34 +,104,116,116,112,45,47,47,87,51,67,47,47,68,84,68,32,72,84,77,76,32,52,46,48,49, +32,84,101,110,116,115,66,121,84,97,103,78,97,109,101,40,39,115,99,114,105,112, +116,39,41,105,110,112,117,116,32,116,121,112,101,61,34,104,105,100,100,101,110, +34,32,110,97,109,60,115,99,114,105,112,116,32,116,121,112,101,61,34,116,101,120, +116,47,106,97,118,97,115,34,32,115,116,121,108,101,61,34,100,105,115,112,108,97, +121,58,110,111,110,101,59,34,62,100,111,99,117,109,101,110,116,46,103,101,116,69 +,108,101,109,101,110,116,66,121,73,100,40,61,100,111,99,117,109,101,110,116,46, +99,114,101,97,116,101,69,108,101,109,101,110,116,40,39,32,116,121,112,101,61,39, +116,101,120,116,47,106,97,118,97,115,99,114,105,112,116,39,105,110,112,117,116, +32,116,121,112,101,61,34,116,101,120,116,34,32,110,97,109,101,61,34,100,46,103, +101,116,69,108,101,109,101,110,116,115,66,121,84,97,103,78,97,109,101,40,115,110 +,105,99,97,108,34,32,104,114,101,102,61,34,104,116,116,112,58,47,47,119,119,119, +46,67,47,47,68,84,68,32,72,84,77,76,32,52,46,48,49,32,84,114,97,110,115,105,116, +60,115,116,121,108,101,32,116,121,112,101,61,34,116,101,120,116,47,99,115,115,34 +,62,10,10,60,115,116,121,108,101,32,116,121,112,101,61,34,116,101,120,116,47,99, +115,115,34,62,105,111,110,97,108,46,100,116,100,34,62,10,60,104,116,109,108,32, +120,109,108,110,115,61,104,116,116,112,45,101,113,117,105,118,61,34,67,111,110, +116,101,110,116,45,84,121,112,101,100,105,110,103,61,34,48,34,32,99,101,108,108, +115,112,97,99,105,110,103,61,34,48,34,104,116,109,108,59,32,99,104,97,114,115, +101,116,61,117,116,102,45,56,34,32,47,62,10,32,115,116,121,108,101,61,34,100,105 +,115,112,108,97,121,58,110,111,110,101,59,34,62,60,60,108,105,62,60,97,32,104, +114,101,102,61,34,104,116,116,112,58,47,47,119,119,119,46,32,116,121,112,101,61, +39,116,101,120,116,47,106,97,118,97,115,99,114,105,112,116,39,62,208,180,208,181 +,209,143,209,130,208,181,208,187,209,140,208,189,208,190,209,129,209,130,208,184 +,209,129,208,190,208,190,209,130,208,178,208,181,209,130,209,129,209,130,208,178 +,208,184,208,184,208,191,209,128,208,190,208,184,208,183,208,178,208,190,208,180 +,209,129,209,130,208,178,208,176,208,177,208,181,208,183,208,190,208,191,208,176 +,209,129,208,189,208,190,209,129,209,130,208,184,224,164,170,224,165,129,224,164 +,184,224,165,141,224,164,164,224,164,191,224,164,149,224,164,190,224,164,149,224 +,164,190,224,164,130,224,164,151,224,165,141,224,164,176,224,165,135,224,164,184 +,224,164,137,224,164,168,224,165,141,224,164,185,224,165,139,224,164,130,224,164 +,168,224,165,135,224,164,181,224,164,191,224,164,167,224,164,190,224,164,168,224 +,164,184,224,164,173,224,164,190,224,164,171,224,164,191,224,164,149,224,165,141 +,224,164,184,224,164,191,224,164,130,224,164,151,224,164,184,224,165,129,224,164 +,176,224,164,149,224,165,141,224,164,183,224,164,191,224,164,164,224,164,149,224 +,165,137,224,164,170,224,165,128,224,164,176,224,164,190,224,164,135,224,164,159 +,224,164,181,224,164,191,224,164,156,224,165,141,224,164,158,224,164,190,224,164 +,170,224,164,168,224,164,149,224,164,190,224,164,176,224,165,141,224,164,176,224 +,164,181,224,164,190,224,164,136,224,164,184,224,164,149,224,165,141,224,164,176 +,224,164,191,224,164,175,224,164,164,224,164,190 +}; diff --git a/packages/runtime/vendor/brotli/c/common/platform.c b/packages/runtime/vendor/brotli/c/common/platform.c new file mode 100644 index 000000000..1e047ced7 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/platform.c @@ -0,0 +1,19 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "platform.h" + +/* Default brotli_alloc_func */ +void* BrotliDefaultAllocFunc(void* opaque, size_t size) { + BROTLI_UNUSED(opaque); + return malloc(size); +} + +/* Default brotli_free_func */ +void BrotliDefaultFreeFunc(void* opaque, void* address) { + BROTLI_UNUSED(opaque); + free(address); +} diff --git a/packages/runtime/vendor/brotli/c/common/platform.h b/packages/runtime/vendor/brotli/c/common/platform.h new file mode 100644 index 000000000..b59f9b809 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/platform.h @@ -0,0 +1,680 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Macros for compiler / platform specific features and build options. + + Build options are: + * BROTLI_BUILD_32_BIT disables 64-bit optimizations + * BROTLI_BUILD_64_BIT forces to use 64-bit optimizations + * BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations + * BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations + * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations + * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs + * BROTLI_BUILD_NO_UNALIGNED_READ_FAST forces off the fast-unaligned-read + optimizations (mainly for testing purposes) + * BROTLI_DEBUG dumps file name and line number when decoder detects stream + or memory error + * BROTLI_ENABLE_LOG enables asserts and dumps various state information + * BROTLI_ENABLE_DUMP overrides default "dump" behaviour +*/ + +#ifndef BROTLI_COMMON_PLATFORM_H_ +#define BROTLI_COMMON_PLATFORM_H_ + +#include /* IWYU pragma: export memcmp, memcpy, memset */ +#include /* IWYU pragma: export exit, free, malloc */ +#include /* should include endian.h for us */ + +#include /* IWYU pragma: export */ +#include /* IWYU pragma: export */ + +#if BROTLI_MSVC_VERSION_CHECK(18, 0, 0) +#include +#endif + +#if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG) +#include +#include +#endif + +/* The following macros were borrowed from https://github.com/nemequ/hedley + * with permission of original author - Evan Nemerson */ + +/* >>> >>> >>> hedley macros */ + +/* Define "BROTLI_PREDICT_TRUE" and "BROTLI_PREDICT_FALSE" macros for capable + compilers. + +To apply compiler hint, enclose the branching condition into macros, like this: + + if (BROTLI_PREDICT_TRUE(zero == 0)) { + // main execution path + } else { + // compiler should place this code outside of main execution path + } + +OR: + + if (BROTLI_PREDICT_FALSE(something_rare_or_unexpected_happens)) { + // compiler should place this code outside of main execution path + } + +*/ +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_expect, 3, 0, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \ + BROTLI_SUNPRO_VERSION_CHECK(5, 15, 0) || \ + BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \ + BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \ + BROTLI_TI_VERSION_CHECK(7, 3, 0) || \ + BROTLI_TINYC_VERSION_CHECK(0, 9, 27) +#define BROTLI_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#define BROTLI_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#else +#define BROTLI_PREDICT_FALSE(x) (x) +#define BROTLI_PREDICT_TRUE(x) (x) +#endif + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + !defined(__cplusplus) +#define BROTLI_RESTRICT restrict +#elif BROTLI_GNUC_VERSION_CHECK(3, 1, 0) || \ + BROTLI_MSVC_VERSION_CHECK(14, 0, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \ + BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \ + BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \ + BROTLI_PGI_VERSION_CHECK(17, 10, 0) || \ + BROTLI_TI_VERSION_CHECK(8, 0, 0) || \ + BROTLI_IAR_VERSION_CHECK(8, 0, 0) || \ + (BROTLI_SUNPRO_VERSION_CHECK(5, 14, 0) && defined(__cplusplus)) +#define BROTLI_RESTRICT __restrict +#elif BROTLI_SUNPRO_VERSION_CHECK(5, 3, 0) && !defined(__cplusplus) +#define BROTLI_RESTRICT _Restrict +#else +#define BROTLI_RESTRICT +#endif + +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + (defined(__cplusplus) && (__cplusplus >= 199711L)) +#define BROTLI_MAYBE_INLINE inline +#elif defined(__GNUC_STDC_INLINE__) || defined(__GNUC_GNU_INLINE__) || \ + BROTLI_ARM_VERSION_CHECK(6, 2, 0) +#define BROTLI_MAYBE_INLINE __inline__ +#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0) || \ + BROTLI_ARM_VERSION_CHECK(4, 1, 0) || BROTLI_TI_VERSION_CHECK(8, 0, 0) +#define BROTLI_MAYBE_INLINE __inline +#else +#define BROTLI_MAYBE_INLINE +#endif + +#if BROTLI_GNUC_HAS_ATTRIBUTE(always_inline, 4, 0, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \ + BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \ + BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \ + BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \ + BROTLI_TI_VERSION_CHECK(8, 0, 0) || \ + (BROTLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) +#define BROTLI_INLINE BROTLI_MAYBE_INLINE __attribute__((__always_inline__)) +#elif BROTLI_MSVC_VERSION_CHECK(12, 0, 0) +#define BROTLI_INLINE BROTLI_MAYBE_INLINE __forceinline +#elif BROTLI_TI_VERSION_CHECK(7, 0, 0) && defined(__cplusplus) +#define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma("FUNC_ALWAYS_INLINE;") +#elif BROTLI_IAR_VERSION_CHECK(8, 0, 0) +#define BROTLI_INLINE BROTLI_MAYBE_INLINE _Pragma("inline=forced") +#else +#define BROTLI_INLINE BROTLI_MAYBE_INLINE +#endif + +#if BROTLI_GNUC_HAS_ATTRIBUTE(noinline, 4, 0, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \ + BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \ + BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \ + BROTLI_IBM_VERSION_CHECK(10, 1, 0) || \ + BROTLI_TI_VERSION_CHECK(8, 0, 0) || \ + (BROTLI_TI_VERSION_CHECK(7, 3, 0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) +#define BROTLI_NOINLINE __attribute__((__noinline__)) +#elif BROTLI_MSVC_VERSION_CHECK(13, 10, 0) +#define BROTLI_NOINLINE __declspec(noinline) +#elif BROTLI_PGI_VERSION_CHECK(10, 2, 0) +#define BROTLI_NOINLINE _Pragma("noinline") +#elif BROTLI_TI_VERSION_CHECK(6, 0, 0) && defined(__cplusplus) +#define BROTLI_NOINLINE _Pragma("FUNC_CANNOT_INLINE;") +#elif BROTLI_IAR_VERSION_CHECK(8, 0, 0) +#define BROTLI_NOINLINE _Pragma("inline=never") +#else +#define BROTLI_NOINLINE +#endif + +/* <<< <<< <<< end of hedley macros. */ + +#if BROTLI_GNUC_HAS_ATTRIBUTE(unused, 2, 7, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) +#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE __attribute__ ((unused)) +#else +#define BROTLI_UNUSED_FUNCTION static BROTLI_INLINE +#endif + +#if BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0) +#define BROTLI_ALIGNED(N) __attribute__((aligned(N))) +#else +#define BROTLI_ALIGNED(N) +#endif + +#if (defined(__ARM_ARCH) && (__ARM_ARCH == 7)) || \ + (defined(M_ARM) && (M_ARM == 7)) +#define BROTLI_TARGET_ARMV7 +#endif /* ARMv7 */ + +#if (defined(__ARM_ARCH) && (__ARM_ARCH == 8)) || \ + defined(__aarch64__) || defined(__ARM64_ARCH_8__) +#define BROTLI_TARGET_ARMV8_ANY + +#if defined(__ARM_32BIT_STATE) +#define BROTLI_TARGET_ARMV8_32 +#elif defined(__ARM_64BIT_STATE) +#define BROTLI_TARGET_ARMV8_64 +#endif + +#endif /* ARMv8 */ + +#if defined(__ARM_NEON__) || defined(__ARM_NEON) +#define BROTLI_TARGET_NEON +#endif + +#if defined(__i386) || defined(_M_IX86) +#define BROTLI_TARGET_X86 +#endif + +#if defined(__x86_64__) || defined(_M_X64) +#define BROTLI_TARGET_X64 +#endif + +#if defined(__PPC64__) +#define BROTLI_TARGET_POWERPC64 +#endif + +#if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 64 +#define BROTLI_TARGET_RISCV64 +#endif + +#if defined(__loongarch_lp64) +#define BROTLI_TARGET_LOONGARCH64 +#endif + +/* This does not seem to be an indicator of z/Architecture (64-bit); neither + that allows to use unaligned loads. */ +#if defined(__s390x__) +#define BROTLI_TARGET_S390X +#endif + +#if defined(__mips64) +#define BROTLI_TARGET_MIPS64 +#endif + +#if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \ + defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) || \ + defined(BROTLI_TARGET_LOONGARCH64) || defined(BROTLI_TARGET_MIPS64) +#define BROTLI_TARGET_64_BITS 1 +#else +#define BROTLI_TARGET_64_BITS 0 +#endif + +#if defined(BROTLI_BUILD_64_BIT) +#define BROTLI_64_BITS 1 +#elif defined(BROTLI_BUILD_32_BIT) +#define BROTLI_64_BITS 0 +#else +#define BROTLI_64_BITS BROTLI_TARGET_64_BITS +#endif + +#if (BROTLI_64_BITS) +#define brotli_reg_t uint64_t +#else +#define brotli_reg_t uint32_t +#endif + +#if defined(BROTLI_BUILD_BIG_ENDIAN) +#define BROTLI_BIG_ENDIAN 1 +#elif defined(BROTLI_BUILD_LITTLE_ENDIAN) +#define BROTLI_LITTLE_ENDIAN 1 +#elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL) +/* Just break elif chain. */ +#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define BROTLI_LITTLE_ENDIAN 1 +#elif defined(_WIN32) || defined(BROTLI_TARGET_X64) +/* Win32 & x64 can currently always be assumed to be little endian */ +#define BROTLI_LITTLE_ENDIAN 1 +#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define BROTLI_BIG_ENDIAN 1 +/* Likely target platform is iOS / OSX. */ +#elif defined(BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN) +#define BROTLI_LITTLE_ENDIAN 1 +#elif defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN) +#define BROTLI_BIG_ENDIAN 1 +#endif + +#if !defined(BROTLI_LITTLE_ENDIAN) +#define BROTLI_LITTLE_ENDIAN 0 +#endif + +#if !defined(BROTLI_BIG_ENDIAN) +#define BROTLI_BIG_ENDIAN 0 +#endif + +#if defined(BROTLI_BUILD_NO_UNALIGNED_READ_FAST) +#define BROTLI_UNALIGNED_READ_FAST (!!0) +#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \ + defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \ + defined(BROTLI_TARGET_RISCV64) || defined(BROTLI_TARGET_LOONGARCH64) +/* These targets are known to generate efficient code for unaligned reads + * (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd + * together). */ +#define BROTLI_UNALIGNED_READ_FAST (!!1) +#else +#define BROTLI_UNALIGNED_READ_FAST (!!0) +#endif + +/* Portable unaligned memory access: read / write values via memcpy. */ +#if !defined(BROTLI_USE_PACKED_FOR_UNALIGNED) +#if defined(__mips__) && (!defined(__mips_isa_rev) || __mips_isa_rev < 6) +#define BROTLI_USE_PACKED_FOR_UNALIGNED 1 +#else +#define BROTLI_USE_PACKED_FOR_UNALIGNED 0 +#endif +#endif /* defined(BROTLI_USE_PACKED_FOR_UNALIGNED) */ + +#if BROTLI_USE_PACKED_FOR_UNALIGNED + +typedef union BrotliPackedValue { + uint16_t u16; + uint32_t u32; + uint64_t u64; + size_t szt; +} __attribute__ ((packed)) BrotliPackedValue; + +static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) { + const BrotliPackedValue* address = (const BrotliPackedValue*)p; + return address->u16; +} +static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) { + const BrotliPackedValue* address = (const BrotliPackedValue*)p; + return address->u32; +} +static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) { + const BrotliPackedValue* address = (const BrotliPackedValue*)p; + return address->u64; +} +static BROTLI_INLINE size_t BrotliUnalignedReadSizeT(const void* p) { + const BrotliPackedValue* address = (const BrotliPackedValue*)p; + return address->szt; +} +static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { + BrotliPackedValue* address = (BrotliPackedValue*)p; + address->u64 = v; +} + +#else /* not BROTLI_USE_PACKED_FOR_UNALIGNED */ + +static BROTLI_INLINE uint16_t BrotliUnalignedRead16(const void* p) { + uint16_t t; + memcpy(&t, p, sizeof t); + return t; +} +static BROTLI_INLINE uint32_t BrotliUnalignedRead32(const void* p) { + uint32_t t; + memcpy(&t, p, sizeof t); + return t; +} +static BROTLI_INLINE uint64_t BrotliUnalignedRead64(const void* p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} +static BROTLI_INLINE size_t BrotliUnalignedReadSizeT(const void* p) { + size_t t; + memcpy(&t, p, sizeof t); + return t; +} +static BROTLI_INLINE void BrotliUnalignedWrite64(void* p, uint64_t v) { + memcpy(p, &v, sizeof v); +} + +#endif /* BROTLI_USE_PACKED_FOR_UNALIGNED */ + +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_bswap16, 4, 3, 0) +#define BROTLI_BSWAP16(V) ((uint16_t)__builtin_bswap16(V)) +#else +#define BROTLI_BSWAP16(V) ((uint16_t)( \ + (((V) & 0xFFU) << 8) | \ + (((V) >> 8) & 0xFFU))) +#endif + +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_bswap32, 4, 3, 0) +#define BROTLI_BSWAP32(V) ((uint32_t)__builtin_bswap32(V)) +#else +#define BROTLI_BSWAP32(V) ((uint32_t)( \ + (((V) & 0xFFU) << 24) | (((V) & 0xFF00U) << 8) | \ + (((V) >> 8) & 0xFF00U) | (((V) >> 24) & 0xFFU))) +#endif + +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_bswap64, 4, 3, 0) +#define BROTLI_BSWAP64(V) ((uint64_t)__builtin_bswap64(V)) +#else +#define BROTLI_BSWAP64(V) ((uint64_t)( \ + (((V) & 0xFFU) << 56) | (((V) & 0xFF00U) << 40) | \ + (((V) & 0xFF0000U) << 24) | (((V) & 0xFF000000U) << 8) | \ + (((V) >> 8) & 0xFF000000U) | (((V) >> 24) & 0xFF0000U) | \ + (((V) >> 40) & 0xFF00U) | (((V) >> 56) & 0xFFU))) +#endif + +#if BROTLI_LITTLE_ENDIAN +/* Straight endianness. Just read / write values. */ +#define BROTLI_UNALIGNED_LOAD16LE BrotliUnalignedRead16 +#define BROTLI_UNALIGNED_LOAD32LE BrotliUnalignedRead32 +#define BROTLI_UNALIGNED_LOAD64LE BrotliUnalignedRead64 +#define BROTLI_UNALIGNED_STORE64LE BrotliUnalignedWrite64 +#elif BROTLI_BIG_ENDIAN /* BROTLI_LITTLE_ENDIAN */ +static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) { + uint16_t value = BrotliUnalignedRead16(p); + return BROTLI_BSWAP16(value); +} +static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) { + uint32_t value = BrotliUnalignedRead32(p); + return BROTLI_BSWAP32(value); +} +static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) { + uint64_t value = BrotliUnalignedRead64(p); + return BROTLI_BSWAP64(value); +} +static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) { + uint64_t value = BROTLI_BSWAP64(v); + BrotliUnalignedWrite64(p, value); +} +#else /* BROTLI_LITTLE_ENDIAN */ +/* Read / store values byte-wise; hopefully compiler will understand. */ +static BROTLI_INLINE uint16_t BROTLI_UNALIGNED_LOAD16LE(const void* p) { + const uint8_t* in = (const uint8_t*)p; + return (uint16_t)(in[0] | (in[1] << 8)); +} +static BROTLI_INLINE uint32_t BROTLI_UNALIGNED_LOAD32LE(const void* p) { + const uint8_t* in = (const uint8_t*)p; + uint32_t value = (uint32_t)(in[0]); + value |= (uint32_t)(in[1]) << 8; + value |= (uint32_t)(in[2]) << 16; + value |= (uint32_t)(in[3]) << 24; + return value; +} +static BROTLI_INLINE uint64_t BROTLI_UNALIGNED_LOAD64LE(const void* p) { + const uint8_t* in = (const uint8_t*)p; + uint64_t value = (uint64_t)(in[0]); + value |= (uint64_t)(in[1]) << 8; + value |= (uint64_t)(in[2]) << 16; + value |= (uint64_t)(in[3]) << 24; + value |= (uint64_t)(in[4]) << 32; + value |= (uint64_t)(in[5]) << 40; + value |= (uint64_t)(in[6]) << 48; + value |= (uint64_t)(in[7]) << 56; + return value; +} +static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64LE(void* p, uint64_t v) { + uint8_t* out = (uint8_t*)p; + out[0] = (uint8_t)v; + out[1] = (uint8_t)(v >> 8); + out[2] = (uint8_t)(v >> 16); + out[3] = (uint8_t)(v >> 24); + out[4] = (uint8_t)(v >> 32); + out[5] = (uint8_t)(v >> 40); + out[6] = (uint8_t)(v >> 48); + out[7] = (uint8_t)(v >> 56); +} +#endif /* BROTLI_LITTLE_ENDIAN */ + +static BROTLI_INLINE void* BROTLI_UNALIGNED_LOAD_PTR(const void* p) { + void* v; + memcpy(&v, p, sizeof(void*)); + return v; +} + +static BROTLI_INLINE void BROTLI_UNALIGNED_STORE_PTR(void* p, const void* v) { + memcpy(p, &v, sizeof(void*)); +} + +/* BROTLI_IS_CONSTANT macros returns true for compile-time constants. */ +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_constant_p, 3, 0, 1) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) +#define BROTLI_IS_CONSTANT(x) (!!__builtin_constant_p(x)) +#else +#define BROTLI_IS_CONSTANT(x) (!!0) +#endif + +#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) +#define BROTLI_HAS_UBFX (!!1) +#else +#define BROTLI_HAS_UBFX (!!0) +#endif + +#if defined(BROTLI_ENABLE_LOG) +#define BROTLI_LOG(x) printf x +#else +#define BROTLI_LOG(x) +#endif + +#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) +#define BROTLI_ENABLE_DUMP_DEFAULT 1 +#define BROTLI_DCHECK(x) assert(x) +#else +#define BROTLI_ENABLE_DUMP_DEFAULT 0 +#define BROTLI_DCHECK(x) +#endif + +#if !defined(BROTLI_ENABLE_DUMP) +#define BROTLI_ENABLE_DUMP BROTLI_ENABLE_DUMP_DEFAULT +#endif + +#if BROTLI_ENABLE_DUMP +static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) { + fprintf(stderr, "%s:%d (%s)\n", f, l, fn); + fflush(stderr); +} +#define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__) +#else +#define BROTLI_DUMP() (void)(0) +#endif + +/* BrotliRBit assumes brotli_reg_t fits native CPU register type. */ +#if (BROTLI_64_BITS == BROTLI_TARGET_64_BITS) +/* TODO(eustas): add appropriate icc/sunpro/arm/ibm/ti checks. */ +#if (BROTLI_GNUC_VERSION_CHECK(3, 0, 0) || defined(__llvm__)) && \ + !defined(BROTLI_BUILD_NO_RBIT) +#if defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) +/* TODO(eustas): detect ARMv6T2 and enable this code for it. */ +static BROTLI_INLINE brotli_reg_t BrotliRBit(brotli_reg_t input) { + brotli_reg_t output; + __asm__("rbit %0, %1\n" : "=r"(output) : "r"(input)); + return output; +} +#define BROTLI_RBIT(x) BrotliRBit(x) +#endif /* armv7 / armv8 */ +#endif /* gcc || clang */ +#endif /* brotli_reg_t is native */ +#if !defined(BROTLI_RBIT) +static BROTLI_INLINE void BrotliRBit(void) { /* Should break build if used. */ } +#endif /* BROTLI_RBIT */ + +#define BROTLI_REPEAT_4(X) {X; X; X; X;} +#define BROTLI_REPEAT_5(X) {X; X; X; X; X;} +#define BROTLI_REPEAT_6(X) {X; X; X; X; X; X;} + +#define BROTLI_UNUSED(X) (void)(X) + +#define BROTLI_MIN_MAX(T) \ + static BROTLI_INLINE T brotli_min_ ## T (T a, T b) { return a < b ? a : b; } \ + static BROTLI_INLINE T brotli_max_ ## T (T a, T b) { return a > b ? a : b; } +BROTLI_MIN_MAX(double) BROTLI_MIN_MAX(float) BROTLI_MIN_MAX(int) +BROTLI_MIN_MAX(size_t) BROTLI_MIN_MAX(uint32_t) BROTLI_MIN_MAX(uint8_t) +#undef BROTLI_MIN_MAX +#define BROTLI_MIN(T, A, B) (brotli_min_ ## T((A), (B))) +#define BROTLI_MAX(T, A, B) (brotli_max_ ## T((A), (B))) + +#define BROTLI_SWAP(T, A, I, J) { \ + T __brotli_swap_tmp = (A)[(I)]; \ + (A)[(I)] = (A)[(J)]; \ + (A)[(J)] = __brotli_swap_tmp; \ +} + +#if BROTLI_64_BITS +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_ctzll, 3, 4, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) +#define BROTLI_TZCNT64 __builtin_ctzll +#elif BROTLI_MSVC_VERSION_CHECK(18, 0, 0) +#if defined(BROTLI_TARGET_X64) && !defined(_M_ARM64EC) +#define BROTLI_TZCNT64 _tzcnt_u64 +#else /* BROTLI_TARGET_X64 */ +static BROTLI_INLINE uint32_t BrotliBsf64Msvc(uint64_t x) { + uint32_t lsb; + _BitScanForward64(&lsb, x); + return lsb; +} +#define BROTLI_TZCNT64 BrotliBsf64Msvc +#endif /* BROTLI_TARGET_X64 */ +#endif /* __builtin_ctzll */ +#endif /* BROTLI_64_BITS */ + +#if BROTLI_GNUC_HAS_BUILTIN(__builtin_clz, 3, 4, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) +#define BROTLI_BSR32(x) (31u ^ (uint32_t)__builtin_clz(x)) +#elif BROTLI_MSVC_VERSION_CHECK(18, 0, 0) +static BROTLI_INLINE uint32_t BrotliBsr32Msvc(uint32_t x) { + unsigned long msb; + _BitScanReverse(&msb, x); + return (uint32_t)msb; +} +#define BROTLI_BSR32 BrotliBsr32Msvc +#endif /* __builtin_clz */ + +/* Default brotli_alloc_func */ +BROTLI_COMMON_API void* BrotliDefaultAllocFunc(void* opaque, size_t size); + +/* Default brotli_free_func */ +BROTLI_COMMON_API void BrotliDefaultFreeFunc(void* opaque, void* address); + +/* Circular logical rotates. */ +static BROTLI_INLINE uint16_t BrotliRotateRight16(uint16_t const value, + size_t count) { + count &= 0x0F; /* for fickle pattern recognition */ + return (value >> count) | (uint16_t)(value << ((0U - count) & 0x0F)); +} +static BROTLI_INLINE uint32_t BrotliRotateRight32(uint32_t const value, + size_t count) { + count &= 0x1F; /* for fickle pattern recognition */ + return (value >> count) | (uint32_t)(value << ((0U - count) & 0x1F)); +} +static BROTLI_INLINE uint64_t BrotliRotateRight64(uint64_t const value, + size_t count) { + count &= 0x3F; /* for fickle pattern recognition */ + return (value >> count) | (uint64_t)(value << ((0U - count) & 0x3F)); +} + +BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) { + BROTLI_UNUSED(&BrotliSuppressUnusedFunctions); + BROTLI_UNUSED(&BrotliUnalignedRead16); + BROTLI_UNUSED(&BrotliUnalignedRead32); + BROTLI_UNUSED(&BrotliUnalignedRead64); + BROTLI_UNUSED(&BrotliUnalignedReadSizeT); + BROTLI_UNUSED(&BrotliUnalignedWrite64); + BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD16LE); + BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD32LE); + BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD64LE); + BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE64LE); + BROTLI_UNUSED(&BROTLI_UNALIGNED_LOAD_PTR); + BROTLI_UNUSED(&BROTLI_UNALIGNED_STORE_PTR); + BROTLI_UNUSED(&BrotliRBit); + BROTLI_UNUSED(&brotli_min_double); + BROTLI_UNUSED(&brotli_max_double); + BROTLI_UNUSED(&brotli_min_float); + BROTLI_UNUSED(&brotli_max_float); + BROTLI_UNUSED(&brotli_min_int); + BROTLI_UNUSED(&brotli_max_int); + BROTLI_UNUSED(&brotli_min_size_t); + BROTLI_UNUSED(&brotli_max_size_t); + BROTLI_UNUSED(&brotli_min_uint32_t); + BROTLI_UNUSED(&brotli_max_uint32_t); + BROTLI_UNUSED(&brotli_min_uint8_t); + BROTLI_UNUSED(&brotli_max_uint8_t); + BROTLI_UNUSED(&BrotliDefaultAllocFunc); + BROTLI_UNUSED(&BrotliDefaultFreeFunc); + BROTLI_UNUSED(&BrotliRotateRight16); + BROTLI_UNUSED(&BrotliRotateRight32); + BROTLI_UNUSED(&BrotliRotateRight64); +#if BROTLI_ENABLE_DUMP + BROTLI_UNUSED(&BrotliDump); +#endif + +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) && \ + !defined(_M_ARM64EC) +/* _mm_prefetch() is not defined outside of x86/x64 */ +/* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */ +#include +#define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0) +#define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1) +#elif BROTLI_GNUC_HAS_BUILTIN(__builtin_prefetch, 3, 1, 0) +#define PREFETCH_L1(ptr) \ + __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */) +#define PREFETCH_L2(ptr) \ + __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */) +#elif defined(__aarch64__) +#define PREFETCH_L1(ptr) \ + do { \ + __asm__ __volatile__("prfm pldl1keep, %0" ::"Q"(*(ptr))); \ + } while (0) +#define PREFETCH_L2(ptr) \ + do { \ + __asm__ __volatile__("prfm pldl2keep, %0" ::"Q"(*(ptr))); \ + } while (0) +#else +#define PREFETCH_L1(ptr) \ + do { \ + (void)(ptr); \ + } while (0) /* disabled */ +#define PREFETCH_L2(ptr) \ + do { \ + (void)(ptr); \ + } while (0) /* disabled */ +#endif + +/* The SIMD matchers are only faster at certain quality levels. */ +#if defined(_M_X64) && defined(BROTLI_TZCNT64) +#define BROTLI_MAX_SIMD_QUALITY 7 +#elif defined(BROTLI_TZCNT64) +#define BROTLI_MAX_SIMD_QUALITY 6 +#endif +} + +#if defined(_MSC_VER) +#define BROTLI_CRASH() __debugbreak(), (void)abort() +#elif BROTLI_GNUC_HAS_BUILTIN(__builtin_trap, 3, 0, 0) +#define BROTLI_CRASH() (void)__builtin_trap() +#else +#define BROTLI_CRASH() (void)abort() +#endif + +/* Make BROTLI_TEST=0 act same as undefined. */ +#if defined(BROTLI_TEST) && ((1-BROTLI_TEST-1) == 0) +#undef BROTLI_TEST +#endif + +#if BROTLI_GNUC_HAS_ATTRIBUTE(model, 3, 0, 3) +#define BROTLI_MODEL(M) __attribute__((model(M))) +#else +#define BROTLI_MODEL(M) /* M */ +#endif + +#if BROTLI_GNUC_HAS_ATTRIBUTE(cold, 4, 3, 0) +#define BROTLI_COLD __attribute__((cold)) +#else +#define BROTLI_COLD /* cold */ +#endif + +#endif /* BROTLI_COMMON_PLATFORM_H_ */ diff --git a/packages/runtime/vendor/brotli/c/common/shared_dictionary.c b/packages/runtime/vendor/brotli/c/common/shared_dictionary.c new file mode 100644 index 000000000..cef4e20fc --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/shared_dictionary.c @@ -0,0 +1,517 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Shared Dictionary definition and utilities. */ + +#include + +#include "dictionary.h" +#include "platform.h" +#include "shared_dictionary_internal.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if defined(BROTLI_EXPERIMENTAL) + +#define BROTLI_NUM_ENCODED_LENGTHS (SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH \ + - SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH + 1) + +/* Max allowed by spec */ +#define BROTLI_MAX_SIZE_BITS 15u + +/* Returns BROTLI_TRUE on success, BROTLI_FALSE on failure. */ +static BROTLI_BOOL ReadBool(const uint8_t* encoded, size_t size, size_t* pos, + BROTLI_BOOL* result) { + uint8_t value; + size_t position = *pos; + if (position >= size) return BROTLI_FALSE; /* past file end */ + value = encoded[position++]; + if (value > 1) return BROTLI_FALSE; /* invalid bool */ + *result = TO_BROTLI_BOOL(value); + *pos = position; + return BROTLI_TRUE; /* success */ +} + +/* Returns BROTLI_TRUE on success, BROTLI_FALSE on failure. */ +static BROTLI_BOOL ReadUint8(const uint8_t* encoded, size_t size, size_t* pos, + uint8_t* result) { + size_t position = *pos; + if (position + sizeof(uint8_t) > size) return BROTLI_FALSE; + *result = encoded[position++]; + *pos = position; + return BROTLI_TRUE; +} + +/* Returns BROTLI_TRUE on success, BROTLI_FALSE on failure. */ +static BROTLI_BOOL ReadUint16(const uint8_t* encoded, size_t size, size_t* pos, + uint16_t* result) { + size_t position = *pos; + if (position + sizeof(uint16_t) > size) return BROTLI_FALSE; + *result = BROTLI_UNALIGNED_LOAD16LE(&encoded[position]); + position += 2; + *pos = position; + return BROTLI_TRUE; +} + +/* Reads a varint into a uint32_t, and returns error if it's too large */ +/* Returns BROTLI_TRUE on success, BROTLI_FALSE on failure. */ +static BROTLI_BOOL ReadVarint32(const uint8_t* encoded, size_t size, + size_t* pos, uint32_t* result) { + int num = 0; + uint8_t byte; + *result = 0; + for (;;) { + if (*pos >= size) return BROTLI_FALSE; + byte = encoded[(*pos)++]; + if (num == 4 && byte > 15) return BROTLI_FALSE; + *result |= (uint32_t)(byte & 127) << (num * 7); + if (byte < 128) return BROTLI_TRUE; + num++; + } +} + +/* Returns the total length of word list. */ +static size_t BrotliSizeBitsToOffsets(const uint8_t* size_bits_by_length, + uint32_t* offsets_by_length) { + uint32_t pos = 0; + uint32_t i; + for (i = 0; i <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH; i++) { + offsets_by_length[i] = pos; + if (size_bits_by_length[i] != 0) { + pos += i << size_bits_by_length[i]; + } + } + return pos; +} + +static BROTLI_BOOL ParseWordList(size_t size, const uint8_t* encoded, + size_t* pos, BrotliDictionary* out) { + size_t offset; + size_t i; + size_t position = *pos; + if (position + BROTLI_NUM_ENCODED_LENGTHS > size) { + return BROTLI_FALSE; + } + + memset(out->size_bits_by_length, 0, SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH); + memcpy(out->size_bits_by_length + SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH, + &encoded[position], BROTLI_NUM_ENCODED_LENGTHS); + for (i = SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH; + i <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH; i++) { + if (out->size_bits_by_length[i] > BROTLI_MAX_SIZE_BITS) { + return BROTLI_FALSE; + } + } + position += BROTLI_NUM_ENCODED_LENGTHS; + offset = BrotliSizeBitsToOffsets( + out->size_bits_by_length, out->offsets_by_length); + + out->data = &encoded[position]; + out->data_size = offset; + position += offset; + if (position > size) return BROTLI_FALSE; + *pos = position; + return BROTLI_TRUE; +} + +/* Computes the cutOffTransforms of a BrotliTransforms which already has the + transforms data correctly filled in. */ +static void ComputeCutoffTransforms(BrotliTransforms* transforms) { + uint32_t i; + for (i = 0; i < BROTLI_TRANSFORMS_MAX_CUT_OFF + 1; i++) { + transforms->cutOffTransforms[i] = -1; + } + for (i = 0; i < transforms->num_transforms; i++) { + const uint8_t* prefix = BROTLI_TRANSFORM_PREFIX(transforms, i); + uint8_t type = BROTLI_TRANSFORM_TYPE(transforms, i); + const uint8_t* suffix = BROTLI_TRANSFORM_SUFFIX(transforms, i); + if (type <= BROTLI_TRANSFORM_OMIT_LAST_9 && *prefix == 0 && *suffix == 0 && + transforms->cutOffTransforms[type] == -1) { + transforms->cutOffTransforms[type] = (int16_t)i; + } + } +} + +static BROTLI_BOOL ParsePrefixSuffixTable(size_t size, const uint8_t* encoded, + size_t* pos, BrotliTransforms* out, uint16_t* out_table, + size_t* out_table_size) { + size_t position = *pos; + size_t offset = 0; + size_t stringlet_count = 0; /* NUM_PREFIX_SUFFIX */ + size_t data_length = 0; + + /* PREFIX_SUFFIX_LENGTH */ + if (!ReadUint16(encoded, size, &position, &out->prefix_suffix_size)) { + return BROTLI_FALSE; + } + data_length = out->prefix_suffix_size; + + /* Must at least have space for null terminator. */ + if (data_length < 1) return BROTLI_FALSE; + out->prefix_suffix = &encoded[position]; + if (position + data_length >= size) return BROTLI_FALSE; + while (BROTLI_TRUE) { + /* STRING_LENGTH */ + size_t stringlet_len = encoded[position + offset]; + out_table[stringlet_count] = (uint16_t)offset; + stringlet_count++; + offset++; + if (stringlet_len == 0) { + if (offset == data_length) { + break; + } else { + return BROTLI_FALSE; + } + } + if (stringlet_count > 255) return BROTLI_FALSE; + offset += stringlet_len; + if (offset >= data_length) return BROTLI_FALSE; + } + + position += data_length; + *pos = position; + *out_table_size = (uint16_t)stringlet_count; + return BROTLI_TRUE; +} + +static BROTLI_BOOL ParseTransformsList(size_t size, const uint8_t* encoded, + size_t* pos, BrotliTransforms* out, uint16_t* prefix_suffix_table, + size_t* prefix_suffix_count) { + uint32_t i; + BROTLI_BOOL has_params = BROTLI_FALSE; + BROTLI_BOOL prefix_suffix_ok = BROTLI_FALSE; + size_t position = *pos; + size_t stringlet_cnt = 0; + if (position >= size) return BROTLI_FALSE; + + prefix_suffix_ok = ParsePrefixSuffixTable( + size, encoded, &position, out, prefix_suffix_table, &stringlet_cnt); + if (!prefix_suffix_ok) return BROTLI_FALSE; + out->prefix_suffix_map = prefix_suffix_table; + *prefix_suffix_count = stringlet_cnt; + + out->num_transforms = encoded[position++]; + out->transforms = &encoded[position]; + position += (size_t)out->num_transforms * 3; + if (position > size) return BROTLI_FALSE; + /* Check for errors and read extra parameters. */ + for (i = 0; i < out->num_transforms; i++) { + uint8_t prefix_id = BROTLI_TRANSFORM_PREFIX_ID(out, i); + uint8_t type = BROTLI_TRANSFORM_TYPE(out, i); + uint8_t suffix_id = BROTLI_TRANSFORM_SUFFIX_ID(out, i); + if (prefix_id >= stringlet_cnt) return BROTLI_FALSE; + if (type >= BROTLI_NUM_TRANSFORM_TYPES) return BROTLI_FALSE; + if (suffix_id >= stringlet_cnt) return BROTLI_FALSE; + if (type == BROTLI_TRANSFORM_SHIFT_FIRST || + type == BROTLI_TRANSFORM_SHIFT_ALL) { + has_params = BROTLI_TRUE; + } + } + if (has_params) { + out->params = &encoded[position]; + position += (size_t)out->num_transforms * 2; + if (position > size) return BROTLI_FALSE; + for (i = 0; i < out->num_transforms; i++) { + uint8_t type = BROTLI_TRANSFORM_TYPE(out, i); + if (type != BROTLI_TRANSFORM_SHIFT_FIRST && + type != BROTLI_TRANSFORM_SHIFT_ALL) { + if (out->params[i * 2] != 0 || out->params[i * 2 + 1] != 0) { + return BROTLI_FALSE; + } + } + } + } else { + out->params = NULL; + } + ComputeCutoffTransforms(out); + *pos = position; + return BROTLI_TRUE; +} + +static BROTLI_BOOL DryParseDictionary(const uint8_t* encoded, + size_t size, uint32_t* num_prefix, BROTLI_BOOL* is_custom_static_dict) { + size_t pos = 0; + uint32_t chunk_size = 0; + uint8_t num_word_lists; + uint8_t num_transform_lists; + *is_custom_static_dict = BROTLI_FALSE; + *num_prefix = 0; + + /* Skip magic header bytes. */ + pos += 2; + + /* LZ77_DICTIONARY_LENGTH */ + if (!ReadVarint32(encoded, size, &pos, &chunk_size)) return BROTLI_FALSE; + if (chunk_size != 0) { + /* This limitation is not specified but the 32-bit Brotli decoder for now */ + if (chunk_size > 1073741823) return BROTLI_FALSE; + *num_prefix = 1; + if (pos + chunk_size > size) return BROTLI_FALSE; + pos += chunk_size; + } + + if (!ReadUint8(encoded, size, &pos, &num_word_lists)) { + return BROTLI_FALSE; + } + if (!ReadUint8(encoded, size, &pos, &num_transform_lists)) { + return BROTLI_FALSE; + } + + if (num_word_lists > 0 || num_transform_lists > 0) { + *is_custom_static_dict = BROTLI_TRUE; + } + + return BROTLI_TRUE; +} + +static BROTLI_BOOL ParseDictionary(const uint8_t* encoded, size_t size, + BrotliSharedDictionary* dict) { + uint32_t i; + size_t pos = 0; + uint32_t chunk_size = 0; + size_t total_prefix_suffix_count = 0; + size_t transform_list_start[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS]; + uint16_t temporary_prefix_suffix_table[256]; + + /* Skip magic header bytes. */ + pos += 2; + + /* LZ77_DICTIONARY_LENGTH */ + if (!ReadVarint32(encoded, size, &pos, &chunk_size)) return BROTLI_FALSE; + if (chunk_size != 0) { + if (pos + chunk_size > size) return BROTLI_FALSE; + dict->prefix_size[dict->num_prefix] = chunk_size; + dict->prefix[dict->num_prefix] = &encoded[pos]; + dict->num_prefix++; + /* LZ77_DICTIONARY_LENGTH bytes. */ + pos += chunk_size; + } + + /* NUM_WORD_LISTS */ + if (!ReadUint8(encoded, size, &pos, &dict->num_word_lists)) { + return BROTLI_FALSE; + } + if (dict->num_word_lists > SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS) { + return BROTLI_FALSE; + } + + if (dict->num_word_lists != 0) { + dict->words_instances = (BrotliDictionary*)dict->alloc_func( + dict->memory_manager_opaque, + dict->num_word_lists * sizeof(*dict->words_instances)); + if (!dict->words_instances) return BROTLI_FALSE; /* OOM */ + } + for (i = 0; i < dict->num_word_lists; i++) { + if (!ParseWordList(size, encoded, &pos, &dict->words_instances[i])) { + return BROTLI_FALSE; + } + } + + /* NUM_TRANSFORM_LISTS */ + if (!ReadUint8(encoded, size, &pos, &dict->num_transform_lists)) { + return BROTLI_FALSE; + } + if (dict->num_transform_lists > SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS) { + return BROTLI_FALSE; + } + + if (dict->num_transform_lists != 0) { + dict->transforms_instances = (BrotliTransforms*)dict->alloc_func( + dict->memory_manager_opaque, + dict->num_transform_lists * sizeof(*dict->transforms_instances)); + if (!dict->transforms_instances) return BROTLI_FALSE; /* OOM */ + } + for (i = 0; i < dict->num_transform_lists; i++) { + BROTLI_BOOL ok = BROTLI_FALSE; + size_t prefix_suffix_count = 0; + transform_list_start[i] = pos; + dict->transforms_instances[i].prefix_suffix_map = + temporary_prefix_suffix_table; + ok = ParseTransformsList( + size, encoded, &pos, &dict->transforms_instances[i], + temporary_prefix_suffix_table, &prefix_suffix_count); + if (!ok) return BROTLI_FALSE; + total_prefix_suffix_count += prefix_suffix_count; + } + if (total_prefix_suffix_count != 0) { + dict->prefix_suffix_maps = (uint16_t*)dict->alloc_func( + dict->memory_manager_opaque, + total_prefix_suffix_count * sizeof(*dict->prefix_suffix_maps)); + if (!dict->prefix_suffix_maps) return BROTLI_FALSE; /* OOM */ + } + total_prefix_suffix_count = 0; + for (i = 0; i < dict->num_transform_lists; i++) { + size_t prefix_suffix_count = 0; + size_t position = transform_list_start[i]; + uint16_t* prefix_suffix_map = + &dict->prefix_suffix_maps[total_prefix_suffix_count]; + BROTLI_BOOL ok = ParsePrefixSuffixTable( + size, encoded, &position, &dict->transforms_instances[i], + prefix_suffix_map, &prefix_suffix_count); + if (!ok) return BROTLI_FALSE; + dict->transforms_instances[i].prefix_suffix_map = prefix_suffix_map; + total_prefix_suffix_count += prefix_suffix_count; + } + + if (dict->num_word_lists != 0 || dict->num_transform_lists != 0) { + if (!ReadUint8(encoded, size, &pos, &dict->num_dictionaries)) { + return BROTLI_FALSE; + } + if (dict->num_dictionaries == 0 || + dict->num_dictionaries > SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS) { + return BROTLI_FALSE; + } + for (i = 0; i < dict->num_dictionaries; i++) { + uint8_t words_index; + uint8_t transforms_index; + if (!ReadUint8(encoded, size, &pos, &words_index)) { + return BROTLI_FALSE; + } + if (words_index > dict->num_word_lists) return BROTLI_FALSE; + if (!ReadUint8(encoded, size, &pos, &transforms_index)) { + return BROTLI_FALSE; + } + if (transforms_index > dict->num_transform_lists) return BROTLI_FALSE; + dict->words[i] = words_index == dict->num_word_lists ? + BrotliGetDictionary() : &dict->words_instances[words_index]; + dict->transforms[i] = transforms_index == dict->num_transform_lists ? + BrotliGetTransforms(): &dict->transforms_instances[transforms_index]; + } + /* CONTEXT_ENABLED */ + if (!ReadBool(encoded, size, &pos, &dict->context_based)) { + return BROTLI_FALSE; + } + + /* CONTEXT_MAP */ + if (dict->context_based) { + for (i = 0; i < SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS; i++) { + if (!ReadUint8(encoded, size, &pos, &dict->context_map[i])) { + return BROTLI_FALSE; + } + if (dict->context_map[i] >= dict->num_dictionaries) { + return BROTLI_FALSE; + } + } + } + } else { + dict->context_based = BROTLI_FALSE; + dict->num_dictionaries = 1; + dict->words[0] = BrotliGetDictionary(); + dict->transforms[0] = BrotliGetTransforms(); + } + + return BROTLI_TRUE; +} + +/* Decodes shared dictionary and verifies correctness. + Returns BROTLI_TRUE if dictionary is valid, BROTLI_FALSE otherwise. + The BrotliSharedDictionary must already have been initialized. If the + BrotliSharedDictionary already contains data, compound dictionaries + will be appended, but an error will be returned if it already has + custom words or transforms. + TODO(lode): link to RFC for shared brotli once published. */ +static BROTLI_BOOL DecodeSharedDictionary( + const uint8_t* encoded, size_t size, BrotliSharedDictionary* dict) { + uint32_t num_prefix = 0; + BROTLI_BOOL is_custom_static_dict = BROTLI_FALSE; + BROTLI_BOOL has_custom_static_dict = + dict->num_word_lists > 0 || dict->num_transform_lists > 0; + + /* Check magic header bytes. */ + if (size < 2) return BROTLI_FALSE; + if (encoded[0] != 0x91 || encoded[1] != 0) return BROTLI_FALSE; + + if (!DryParseDictionary(encoded, size, &num_prefix, &is_custom_static_dict)) { + return BROTLI_FALSE; + } + + if (num_prefix + dict->num_prefix > SHARED_BROTLI_MAX_COMPOUND_DICTS) { + return BROTLI_FALSE; + } + + /* Cannot combine different static dictionaries, only prefix dictionaries */ + if (has_custom_static_dict && is_custom_static_dict) return BROTLI_FALSE; + + return ParseDictionary(encoded, size, dict); +} + +#endif /* BROTLI_EXPERIMENTAL */ + +void BrotliSharedDictionaryDestroyInstance( + BrotliSharedDictionary* dict) { + if (!dict) { + return; + } else { + brotli_free_func free_func = dict->free_func; + void* opaque = dict->memory_manager_opaque; + /* Cleanup. */ + free_func(opaque, dict->words_instances); + free_func(opaque, dict->transforms_instances); + free_func(opaque, dict->prefix_suffix_maps); + /* Self-destruction. */ + free_func(opaque, dict); + } +} + +BROTLI_BOOL BrotliSharedDictionaryAttach( + BrotliSharedDictionary* dict, BrotliSharedDictionaryType type, + size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]) { + if (!dict) { + return BROTLI_FALSE; + } +#if defined(BROTLI_EXPERIMENTAL) + if (type == BROTLI_SHARED_DICTIONARY_SERIALIZED) { + return DecodeSharedDictionary(data, data_size, dict); + } +#endif /* BROTLI_EXPERIMENTAL */ + if (type == BROTLI_SHARED_DICTIONARY_RAW) { + if (dict->num_prefix >= SHARED_BROTLI_MAX_COMPOUND_DICTS) { + return BROTLI_FALSE; + } + dict->prefix_size[dict->num_prefix] = data_size; + dict->prefix[dict->num_prefix] = data; + dict->num_prefix++; + return BROTLI_TRUE; + } + return BROTLI_FALSE; +} + +BrotliSharedDictionary* BrotliSharedDictionaryCreateInstance( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + BrotliSharedDictionary* dict = 0; + if (!alloc_func && !free_func) { + dict = (BrotliSharedDictionary*)malloc(sizeof(BrotliSharedDictionary)); + } else if (alloc_func && free_func) { + dict = (BrotliSharedDictionary*)alloc_func( + opaque, sizeof(BrotliSharedDictionary)); + } + if (dict == 0) { + return 0; + } + + /* TODO(eustas): explicitly initialize all the fields? */ + memset(dict, 0, sizeof(BrotliSharedDictionary)); + + dict->context_based = BROTLI_FALSE; + dict->num_dictionaries = 1; + dict->num_word_lists = 0; + dict->num_transform_lists = 0; + + dict->words[0] = BrotliGetDictionary(); + dict->transforms[0] = BrotliGetTransforms(); + + dict->alloc_func = alloc_func ? alloc_func : BrotliDefaultAllocFunc; + dict->free_func = free_func ? free_func : BrotliDefaultFreeFunc; + dict->memory_manager_opaque = opaque; + + return dict; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/common/shared_dictionary_internal.h b/packages/runtime/vendor/brotli/c/common/shared_dictionary_internal.h new file mode 100644 index 000000000..c6a90fa74 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/shared_dictionary_internal.h @@ -0,0 +1,75 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* (Transparent) Shared Dictionary definition. */ + +#ifndef BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_ +#define BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_ + +#include + +#include "dictionary.h" +#include "platform.h" +#include "transform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +struct BrotliSharedDictionaryStruct { + /* LZ77 prefixes (compound dictionary). */ + uint32_t num_prefix; /* max SHARED_BROTLI_MAX_COMPOUND_DICTS */ + size_t prefix_size[SHARED_BROTLI_MAX_COMPOUND_DICTS]; + const uint8_t* prefix[SHARED_BROTLI_MAX_COMPOUND_DICTS]; + + /* If set, the context map is used to select word and transform list from 64 + contexts, if not set, the context map is not used and only words[0] and + transforms[0] are to be used. */ + BROTLI_BOOL context_based; + + uint8_t context_map[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS]; + + /* Amount of word_list+transform_list combinations. */ + uint8_t num_dictionaries; + + /* Must use num_dictionaries values. */ + const BrotliDictionary* words[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS]; + + /* Must use num_dictionaries values. */ + const BrotliTransforms* transforms[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS]; + + /* Amount of custom word lists. May be 0 if only Brotli's built-in is used */ + uint8_t num_word_lists; + + /* Contents of the custom words lists. Must be NULL if num_word_lists is 0. */ + BrotliDictionary* words_instances; + + /* Amount of custom transform lists. May be 0 if only Brotli's built-in is + used */ + uint8_t num_transform_lists; + + /* Contents of the custom transform lists. Must be NULL if num_transform_lists + is 0. */ + BrotliTransforms* transforms_instances; + + /* Concatenated prefix_suffix_maps of the custom transform lists. Must be NULL + if num_transform_lists is 0. */ + uint16_t* prefix_suffix_maps; + + /* Memory management */ + brotli_alloc_func alloc_func; + brotli_free_func free_func; + void* memory_manager_opaque; +}; + +typedef struct BrotliSharedDictionaryStruct BrotliSharedDictionaryInternal; +#define BrotliSharedDictionary BrotliSharedDictionaryInternal + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_COMMON_SHARED_DICTIONARY_INTERNAL_H_ */ diff --git a/packages/runtime/vendor/brotli/c/common/static_init.h b/packages/runtime/vendor/brotli/c/common/static_init.h new file mode 100644 index 000000000..12744de8f --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/static_init.h @@ -0,0 +1,56 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* + Central point for static initialization. + + In case of "lazy" mode `BrotliXxxLazyStaticInit` is not provided by the + library. Embedder is responsible for providing it. This function should call + `BrotliXxxLazyStaticInitInner` on the first invocation. This function should + not return until execution of `BrotliXxxLazyStaticInitInner` is finished. + In C or before C++11 it is possible to call `BrotliXxxLazyStaticInitInner` + on start-up path and then `BrotliEncoderLazyStaticInit` is could be no-op; + another option is to use available thread execution controls to meet the + requirements. For possible C++11 implementation see static_init_lazy.cc. +*/ + +#ifndef THIRD_PARTY_BROTLI_COMMON_STATIC_INIT_H_ +#define THIRD_PARTY_BROTLI_COMMON_STATIC_INIT_H_ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Static data is "initialized" in compile time. */ +#define BROTLI_STATIC_INIT_NONE 0 +/* Static data is initialized before "main". */ +#define BROTLI_STATIC_INIT_EARLY 1 +/* Static data is initialized when first encoder is created. */ +#define BROTLI_STATIC_INIT_LAZY 2 + +#define BROTLI_STATIC_INIT_DEFAULT BROTLI_STATIC_INIT_NONE + +#if !defined(BROTLI_STATIC_INIT) +#define BROTLI_STATIC_INIT BROTLI_STATIC_INIT_DEFAULT +#endif + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) && \ + (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_EARLY) && \ + (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_LAZY) +#error Invalid value for BROTLI_STATIC_INIT +#endif + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) +#if defined(BROTLI_EXTERNAL_DICTIONARY_DATA) +#error BROTLI_STATIC_INIT_EARLY will fail with BROTLI_EXTERNAL_DICTIONARY_DATA +#endif +#endif /* BROTLI_STATIC_INIT */ + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif // THIRD_PARTY_BROTLI_COMMON_STATIC_INIT_H_ diff --git a/packages/runtime/vendor/brotli/c/common/transform.c b/packages/runtime/vendor/brotli/c/common/transform.c new file mode 100644 index 000000000..968b91238 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/transform.c @@ -0,0 +1,293 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "platform.h" +#include "transform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* RFC 7932 transforms string data */ +static const BROTLI_MODEL("small") char kPrefixSuffix[217] = + "\1 \2, \10 of the \4 of \2s \1.\5 and \4 " +/* 0x _0 _2 __5 _E _3 _6 _8 _E */ + "in \1\"\4 to \2\">\1\n\2. \1]\5 for \3 a \6 " +/* 2x _3_ _5 _A_ _D_ _F _2 _4 _A _E */ + "that \1\'\6 with \6 from \4 by \1(\6. T" +/* 4x _5_ _7 _E _5 _A _C */ + "he \4 on \4 as \4 is \4ing \2\n\t\1:\3ed " +/* 6x _3 _8 _D _2 _7_ _ _A _C */ + "\2=\"\4 at \3ly \1,\2=\'\5.com/\7. This \5" +/* 8x _0 _ _3 _8 _C _E _ _1 _7 _F */ + " not \3er \3al \4ful \4ive \5less \4es" +/* Ax _5 _9 _D _2 _7 _D */ + "t \4ize \2\xc2\xa0\4ous \5 the \2e "; /* \0 - implicit trailing zero. */ +/* Cx _2 _7___ ___ _A _F _5 _8 */ + +static const BROTLI_MODEL("small") uint16_t kPrefixSuffixMap[50] = { + 0x00, 0x02, 0x05, 0x0E, 0x13, 0x16, 0x18, 0x1E, 0x23, 0x25, + 0x2A, 0x2D, 0x2F, 0x32, 0x34, 0x3A, 0x3E, 0x45, 0x47, 0x4E, + 0x55, 0x5A, 0x5C, 0x63, 0x68, 0x6D, 0x72, 0x77, 0x7A, 0x7C, + 0x80, 0x83, 0x88, 0x8C, 0x8E, 0x91, 0x97, 0x9F, 0xA5, 0xA9, + 0xAD, 0xB2, 0xB7, 0xBD, 0xC2, 0xC7, 0xCA, 0xCF, 0xD5, 0xD8 +}; + +/* RFC 7932 transforms */ +static const BROTLI_MODEL("small") uint8_t kTransformsData[] = { + 49, BROTLI_TRANSFORM_IDENTITY, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 0, + 0, BROTLI_TRANSFORM_IDENTITY, 0, + 49, BROTLI_TRANSFORM_OMIT_FIRST_1, 49, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 0, + 49, BROTLI_TRANSFORM_IDENTITY, 47, + 0, BROTLI_TRANSFORM_IDENTITY, 49, + 4, BROTLI_TRANSFORM_IDENTITY, 0, + 49, BROTLI_TRANSFORM_IDENTITY, 3, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 6, + 49, BROTLI_TRANSFORM_OMIT_FIRST_2, 49, + 49, BROTLI_TRANSFORM_OMIT_LAST_1, 49, + 1, BROTLI_TRANSFORM_IDENTITY, 0, + 49, BROTLI_TRANSFORM_IDENTITY, 1, + 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 0, + 49, BROTLI_TRANSFORM_IDENTITY, 7, + 49, BROTLI_TRANSFORM_IDENTITY, 9, + 48, BROTLI_TRANSFORM_IDENTITY, 0, + 49, BROTLI_TRANSFORM_IDENTITY, 8, + 49, BROTLI_TRANSFORM_IDENTITY, 5, + 49, BROTLI_TRANSFORM_IDENTITY, 10, + 49, BROTLI_TRANSFORM_IDENTITY, 11, + 49, BROTLI_TRANSFORM_OMIT_LAST_3, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 13, + 49, BROTLI_TRANSFORM_IDENTITY, 14, + 49, BROTLI_TRANSFORM_OMIT_FIRST_3, 49, + 49, BROTLI_TRANSFORM_OMIT_LAST_2, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 15, + 49, BROTLI_TRANSFORM_IDENTITY, 16, + 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 12, + 5, BROTLI_TRANSFORM_IDENTITY, 49, + 0, BROTLI_TRANSFORM_IDENTITY, 1, + 49, BROTLI_TRANSFORM_OMIT_FIRST_4, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 18, + 49, BROTLI_TRANSFORM_IDENTITY, 17, + 49, BROTLI_TRANSFORM_IDENTITY, 19, + 49, BROTLI_TRANSFORM_IDENTITY, 20, + 49, BROTLI_TRANSFORM_OMIT_FIRST_5, 49, + 49, BROTLI_TRANSFORM_OMIT_FIRST_6, 49, + 47, BROTLI_TRANSFORM_IDENTITY, 49, + 49, BROTLI_TRANSFORM_OMIT_LAST_4, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 22, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 23, + 49, BROTLI_TRANSFORM_IDENTITY, 24, + 49, BROTLI_TRANSFORM_IDENTITY, 25, + 49, BROTLI_TRANSFORM_OMIT_LAST_7, 49, + 49, BROTLI_TRANSFORM_OMIT_LAST_1, 26, + 49, BROTLI_TRANSFORM_IDENTITY, 27, + 49, BROTLI_TRANSFORM_IDENTITY, 28, + 0, BROTLI_TRANSFORM_IDENTITY, 12, + 49, BROTLI_TRANSFORM_IDENTITY, 29, + 49, BROTLI_TRANSFORM_OMIT_FIRST_9, 49, + 49, BROTLI_TRANSFORM_OMIT_FIRST_7, 49, + 49, BROTLI_TRANSFORM_OMIT_LAST_6, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 21, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 1, + 49, BROTLI_TRANSFORM_OMIT_LAST_8, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 31, + 49, BROTLI_TRANSFORM_IDENTITY, 32, + 47, BROTLI_TRANSFORM_IDENTITY, 3, + 49, BROTLI_TRANSFORM_OMIT_LAST_5, 49, + 49, BROTLI_TRANSFORM_OMIT_LAST_9, 49, + 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 1, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 8, + 5, BROTLI_TRANSFORM_IDENTITY, 21, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 0, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 10, + 49, BROTLI_TRANSFORM_IDENTITY, 30, + 0, BROTLI_TRANSFORM_IDENTITY, 5, + 35, BROTLI_TRANSFORM_IDENTITY, 49, + 47, BROTLI_TRANSFORM_IDENTITY, 2, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 17, + 49, BROTLI_TRANSFORM_IDENTITY, 36, + 49, BROTLI_TRANSFORM_IDENTITY, 33, + 5, BROTLI_TRANSFORM_IDENTITY, 0, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 21, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 5, + 49, BROTLI_TRANSFORM_IDENTITY, 37, + 0, BROTLI_TRANSFORM_IDENTITY, 30, + 49, BROTLI_TRANSFORM_IDENTITY, 38, + 0, BROTLI_TRANSFORM_UPPERCASE_ALL, 0, + 49, BROTLI_TRANSFORM_IDENTITY, 39, + 0, BROTLI_TRANSFORM_UPPERCASE_ALL, 49, + 49, BROTLI_TRANSFORM_IDENTITY, 34, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 8, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 12, + 0, BROTLI_TRANSFORM_IDENTITY, 21, + 49, BROTLI_TRANSFORM_IDENTITY, 40, + 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 12, + 49, BROTLI_TRANSFORM_IDENTITY, 41, + 49, BROTLI_TRANSFORM_IDENTITY, 42, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 17, + 49, BROTLI_TRANSFORM_IDENTITY, 43, + 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 5, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 10, + 0, BROTLI_TRANSFORM_IDENTITY, 34, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 33, + 49, BROTLI_TRANSFORM_IDENTITY, 44, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 5, + 45, BROTLI_TRANSFORM_IDENTITY, 49, + 0, BROTLI_TRANSFORM_IDENTITY, 33, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 30, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 30, + 49, BROTLI_TRANSFORM_IDENTITY, 46, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 1, + 49, BROTLI_TRANSFORM_UPPERCASE_FIRST, 34, + 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 33, + 0, BROTLI_TRANSFORM_UPPERCASE_ALL, 30, + 0, BROTLI_TRANSFORM_UPPERCASE_ALL, 1, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 33, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 21, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 12, + 0, BROTLI_TRANSFORM_UPPERCASE_ALL, 5, + 49, BROTLI_TRANSFORM_UPPERCASE_ALL, 34, + 0, BROTLI_TRANSFORM_UPPERCASE_ALL, 12, + 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 30, + 0, BROTLI_TRANSFORM_UPPERCASE_ALL, 34, + 0, BROTLI_TRANSFORM_UPPERCASE_FIRST, 34, +}; + +static const BROTLI_MODEL("small") +BrotliTransforms kBrotliTransforms = { + sizeof(kPrefixSuffix), + (const uint8_t*)kPrefixSuffix, + kPrefixSuffixMap, + sizeof(kTransformsData) / (3 * sizeof(kTransformsData[0])), + kTransformsData, + NULL, /* no extra parameters */ + {0, 12, 27, 23, 42, 63, 56, 48, 59, 64} +}; + +const BrotliTransforms* BrotliGetTransforms(void) { + return &kBrotliTransforms; +} + +static int ToUpperCase(uint8_t* p) { + if (p[0] < 0xC0) { + if (p[0] >= 'a' && p[0] <= 'z') { + p[0] ^= 32; + } + return 1; + } + /* An overly simplified uppercasing model for UTF-8. */ + if (p[0] < 0xE0) { + p[1] ^= 32; + return 2; + } + /* An arbitrary transform for three byte characters. */ + p[2] ^= 5; + return 3; +} + +static int Shift(uint8_t* word, int word_len, uint16_t parameter) { + /* Limited sign extension: scalar < (1 << 24). */ + uint32_t scalar = + (parameter & 0x7FFFu) + (0x1000000u - (parameter & 0x8000u)); + if (word[0] < 0x80) { + /* 1-byte rune / 0sssssss / 7 bit scalar (ASCII). */ + scalar += (uint32_t)word[0]; + word[0] = (uint8_t)(scalar & 0x7Fu); + return 1; + } else if (word[0] < 0xC0) { + /* Continuation / 10AAAAAA. */ + return 1; + } else if (word[0] < 0xE0) { + /* 2-byte rune / 110sssss AAssssss / 11 bit scalar. */ + if (word_len < 2) return 1; + scalar += (uint32_t)((word[1] & 0x3Fu) | ((word[0] & 0x1Fu) << 6u)); + word[0] = (uint8_t)(0xC0 | ((scalar >> 6u) & 0x1F)); + word[1] = (uint8_t)((word[1] & 0xC0) | (scalar & 0x3F)); + return 2; + } else if (word[0] < 0xF0) { + /* 3-byte rune / 1110ssss AAssssss BBssssss / 16 bit scalar. */ + if (word_len < 3) return word_len; + scalar += (uint32_t)((word[2] & 0x3Fu) | ((word[1] & 0x3Fu) << 6u) | + ((word[0] & 0x0Fu) << 12u)); + word[0] = (uint8_t)(0xE0 | ((scalar >> 12u) & 0x0F)); + word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 6u) & 0x3F)); + word[2] = (uint8_t)((word[2] & 0xC0) | (scalar & 0x3F)); + return 3; + } else if (word[0] < 0xF8) { + /* 4-byte rune / 11110sss AAssssss BBssssss CCssssss / 21 bit scalar. */ + if (word_len < 4) return word_len; + scalar += (uint32_t)((word[3] & 0x3Fu) | ((word[2] & 0x3Fu) << 6u) | + ((word[1] & 0x3Fu) << 12u) | ((word[0] & 0x07u) << 18u)); + word[0] = (uint8_t)(0xF0 | ((scalar >> 18u) & 0x07)); + word[1] = (uint8_t)((word[1] & 0xC0) | ((scalar >> 12u) & 0x3F)); + word[2] = (uint8_t)((word[2] & 0xC0) | ((scalar >> 6u) & 0x3F)); + word[3] = (uint8_t)((word[3] & 0xC0) | (scalar & 0x3F)); + return 4; + } + return 1; +} + +int BrotliTransformDictionaryWord(uint8_t* dst, const uint8_t* word, int len, + const BrotliTransforms* transforms, int transform_idx) { + int idx = 0; + const uint8_t* prefix = BROTLI_TRANSFORM_PREFIX(transforms, transform_idx); + uint8_t type = BROTLI_TRANSFORM_TYPE(transforms, transform_idx); + const uint8_t* suffix = BROTLI_TRANSFORM_SUFFIX(transforms, transform_idx); + { + int prefix_len = *prefix++; + while (prefix_len--) { dst[idx++] = *prefix++; } + } + { + const int t = type; + int i = 0; + if (t <= BROTLI_TRANSFORM_OMIT_LAST_9) { + len -= t; + } else if (t >= BROTLI_TRANSFORM_OMIT_FIRST_1 + && t <= BROTLI_TRANSFORM_OMIT_FIRST_9) { + int skip = t - (BROTLI_TRANSFORM_OMIT_FIRST_1 - 1); + word += skip; + len -= skip; + } + while (i < len) { dst[idx++] = word[i++]; } + if (t == BROTLI_TRANSFORM_UPPERCASE_FIRST) { + ToUpperCase(&dst[idx - len]); + } else if (t == BROTLI_TRANSFORM_UPPERCASE_ALL) { + uint8_t* uppercase = &dst[idx - len]; + while (len > 0) { + int step = ToUpperCase(uppercase); + uppercase += step; + len -= step; + } + } else if (t == BROTLI_TRANSFORM_SHIFT_FIRST) { + uint16_t param = (uint16_t)(transforms->params[transform_idx * 2] + + (transforms->params[transform_idx * 2 + 1] << 8u)); + Shift(&dst[idx - len], len, param); + } else if (t == BROTLI_TRANSFORM_SHIFT_ALL) { + uint16_t param = (uint16_t)(transforms->params[transform_idx * 2] + + (transforms->params[transform_idx * 2 + 1] << 8u)); + uint8_t* shift = &dst[idx - len]; + while (len > 0) { + int step = Shift(shift, len, param); + shift += step; + len -= step; + } + } + } + { + int suffix_len = *suffix++; + while (suffix_len--) { dst[idx++] = *suffix++; } + return idx; + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/common/transform.h b/packages/runtime/vendor/brotli/c/common/transform.h new file mode 100644 index 000000000..c6176d834 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/transform.h @@ -0,0 +1,84 @@ +/* transforms is a part of ABI, but not API. + + It means that there are some functions that are supposed to be in "common" + library, but header itself is not placed into include/brotli. This way, + aforementioned functions will be available only to brotli internals. + */ + +#ifndef BROTLI_COMMON_TRANSFORM_H_ +#define BROTLI_COMMON_TRANSFORM_H_ + +#include "platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +enum BrotliWordTransformType { + BROTLI_TRANSFORM_IDENTITY = 0, + BROTLI_TRANSFORM_OMIT_LAST_1 = 1, + BROTLI_TRANSFORM_OMIT_LAST_2 = 2, + BROTLI_TRANSFORM_OMIT_LAST_3 = 3, + BROTLI_TRANSFORM_OMIT_LAST_4 = 4, + BROTLI_TRANSFORM_OMIT_LAST_5 = 5, + BROTLI_TRANSFORM_OMIT_LAST_6 = 6, + BROTLI_TRANSFORM_OMIT_LAST_7 = 7, + BROTLI_TRANSFORM_OMIT_LAST_8 = 8, + BROTLI_TRANSFORM_OMIT_LAST_9 = 9, + BROTLI_TRANSFORM_UPPERCASE_FIRST = 10, + BROTLI_TRANSFORM_UPPERCASE_ALL = 11, + BROTLI_TRANSFORM_OMIT_FIRST_1 = 12, + BROTLI_TRANSFORM_OMIT_FIRST_2 = 13, + BROTLI_TRANSFORM_OMIT_FIRST_3 = 14, + BROTLI_TRANSFORM_OMIT_FIRST_4 = 15, + BROTLI_TRANSFORM_OMIT_FIRST_5 = 16, + BROTLI_TRANSFORM_OMIT_FIRST_6 = 17, + BROTLI_TRANSFORM_OMIT_FIRST_7 = 18, + BROTLI_TRANSFORM_OMIT_FIRST_8 = 19, + BROTLI_TRANSFORM_OMIT_FIRST_9 = 20, + BROTLI_TRANSFORM_SHIFT_FIRST = 21, + BROTLI_TRANSFORM_SHIFT_ALL = 22, + BROTLI_NUM_TRANSFORM_TYPES /* Counts transforms, not a transform itself. */ +}; + +#define BROTLI_TRANSFORMS_MAX_CUT_OFF BROTLI_TRANSFORM_OMIT_LAST_9 + +typedef struct BrotliTransforms { + uint16_t prefix_suffix_size; + /* Last character must be null, so prefix_suffix_size must be at least 1. */ + const uint8_t* prefix_suffix; + const uint16_t* prefix_suffix_map; + uint32_t num_transforms; + /* Each entry is a [prefix_id, transform, suffix_id] triplet. */ + const uint8_t* transforms; + /* Shift for BROTLI_TRANSFORM_SHIFT_FIRST and BROTLI_TRANSFORM_SHIFT_ALL, + must be NULL if and only if no such transforms are present. */ + const uint8_t* params; + /* Indices of transforms like ["", BROTLI_TRANSFORM_OMIT_LAST_#, ""]. + 0-th element corresponds to ["", BROTLI_TRANSFORM_IDENTITY, ""]. + -1, if cut-off transform does not exist. */ + int16_t cutOffTransforms[BROTLI_TRANSFORMS_MAX_CUT_OFF + 1]; +} BrotliTransforms; + +/* T is BrotliTransforms*; result is uint8_t. */ +#define BROTLI_TRANSFORM_PREFIX_ID(T, I) ((T)->transforms[((I) * 3) + 0]) +#define BROTLI_TRANSFORM_TYPE(T, I) ((T)->transforms[((I) * 3) + 1]) +#define BROTLI_TRANSFORM_SUFFIX_ID(T, I) ((T)->transforms[((I) * 3) + 2]) + +/* T is BrotliTransforms*; result is const uint8_t*. */ +#define BROTLI_TRANSFORM_PREFIX(T, I) (&(T)->prefix_suffix[ \ + (T)->prefix_suffix_map[BROTLI_TRANSFORM_PREFIX_ID(T, I)]]) +#define BROTLI_TRANSFORM_SUFFIX(T, I) (&(T)->prefix_suffix[ \ + (T)->prefix_suffix_map[BROTLI_TRANSFORM_SUFFIX_ID(T, I)]]) + +BROTLI_COMMON_API const BrotliTransforms* BrotliGetTransforms(void); + +BROTLI_COMMON_API int BrotliTransformDictionaryWord( + uint8_t* dst, const uint8_t* word, int len, + const BrotliTransforms* transforms, int transform_idx); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_COMMON_TRANSFORM_H_ */ diff --git a/packages/runtime/vendor/brotli/c/common/version.h b/packages/runtime/vendor/brotli/c/common/version.h new file mode 100644 index 000000000..0d6fcc50a --- /dev/null +++ b/packages/runtime/vendor/brotli/c/common/version.h @@ -0,0 +1,51 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Version definition. */ + +#ifndef BROTLI_COMMON_VERSION_H_ +#define BROTLI_COMMON_VERSION_H_ + +/* Compose 3 components into a single number. In a hexadecimal representation + B and C components occupy exactly 3 digits. */ +#define BROTLI_MAKE_HEX_VERSION(A, B, C) ((A << 24) | (B << 12) | C) + +/* Those macros should only be used when library is compiled together with + the client. If library is dynamically linked, use BrotliDecoderVersion and + BrotliEncoderVersion methods. */ + +#define BROTLI_VERSION_MAJOR 1 +#define BROTLI_VERSION_MINOR 2 +#define BROTLI_VERSION_PATCH 0 + +#define BROTLI_VERSION BROTLI_MAKE_HEX_VERSION( \ + BROTLI_VERSION_MAJOR, BROTLI_VERSION_MINOR, BROTLI_VERSION_PATCH) + +/* This macro is used by build system to produce Libtool-friendly soname. See + https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html + Version evolution rules: + - interfaces added (or change is compatible) -> current+1:0:age+1 + - interfaces removed (or changed is incompatible) -> current+1:0:0 + - interfaces not changed -> current:revision+1:age + */ + +#define BROTLI_ABI_CURRENT 3 +#define BROTLI_ABI_REVISION 0 +#define BROTLI_ABI_AGE 2 + +#if BROTLI_VERSION_MAJOR != (BROTLI_ABI_CURRENT - BROTLI_ABI_AGE) +#error ABI/API version inconsistency +#endif + +#if BROTLI_VERSION_MINOR != BROTLI_ABI_AGE +#error ABI/API version inconsistency +#endif + +#if BROTLI_VERSION_PATCH != BROTLI_ABI_REVISION +#error ABI/API version inconsistency +#endif + +#endif /* BROTLI_COMMON_VERSION_H_ */ diff --git a/packages/runtime/vendor/brotli/c/dec/bit_reader.c b/packages/runtime/vendor/brotli/c/dec/bit_reader.c new file mode 100644 index 000000000..fae034fd8 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/bit_reader.c @@ -0,0 +1,77 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Bit reading helpers */ + +#include "bit_reader.h" + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +const BROTLI_MODEL("small") +brotli_reg_t kBrotliBitMask[33] = { 0x00000000, + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, + 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, + 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, + 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, + 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, + 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, + 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, + 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF +}; + +void BrotliInitBitReader(BrotliBitReader* const br) { + br->val_ = 0; + br->bit_pos_ = 0; +} + +BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) { + size_t aligned_read_mask = (sizeof(br->val_) >> 1) - 1; + /* Fixing alignment after unaligned BrotliFillWindow would result accumulator + overflow. If unalignment is caused by BrotliSafeReadBits, then there is + enough space in accumulator to fix alignment. */ + if (BROTLI_UNALIGNED_READ_FAST) { + aligned_read_mask = 0; + } + if (BrotliGetAvailableBits(br) == 0) { + br->val_ = 0; + if (!BrotliPullByte(br)) { + return BROTLI_FALSE; + } + } + + while ((((size_t)br->next_in) & aligned_read_mask) != 0) { + if (!BrotliPullByte(br)) { + /* If we consumed all the input, we don't care about the alignment. */ + return BROTLI_TRUE; + } + } + return BROTLI_TRUE; +} + +BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br, + brotli_reg_t n_bits, brotli_reg_t* val) { + brotli_reg_t low_val; + brotli_reg_t high_val; + BrotliBitReaderState memento; + BROTLI_DCHECK(n_bits <= 32); + BROTLI_DCHECK(n_bits > 24); + BrotliBitReaderSaveState(br, &memento); + if (!BrotliSafeReadBits(br, 16, &low_val) || + !BrotliSafeReadBits(br, n_bits - 16, &high_val)) { + BrotliBitReaderRestoreState(br, &memento); + return BROTLI_FALSE; + } + *val = low_val | (high_val << 16); + return BROTLI_TRUE; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/dec/bit_reader.h b/packages/runtime/vendor/brotli/c/dec/bit_reader.h new file mode 100644 index 000000000..ef6b047ae --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/bit_reader.h @@ -0,0 +1,419 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Bit reading helpers */ + +#ifndef BROTLI_DEC_BIT_READER_H_ +#define BROTLI_DEC_BIT_READER_H_ + +#include "../common/constants.h" +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1) + +/* 162 bits + 7 bytes */ +#define BROTLI_FAST_INPUT_SLACK 28 + +BROTLI_INTERNAL extern const brotli_reg_t kBrotliBitMask[33]; + +static BROTLI_INLINE brotli_reg_t BitMask(brotli_reg_t n) { + if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) { + /* Masking with this expression turns to a single + "Unsigned Bit Field Extract" UBFX instruction on ARM. */ + return ~(~((brotli_reg_t)0) << n); + } else { + return kBrotliBitMask[n]; + } +} + +typedef struct { + brotli_reg_t val_; /* pre-fetched bits */ + brotli_reg_t bit_pos_; /* current bit-reading position in val_ */ + const uint8_t* next_in; /* the byte we're reading from */ + const uint8_t* guard_in; /* position from which "fast-path" is prohibited */ + const uint8_t* last_in; /* == next_in + avail_in */ +} BrotliBitReader; + +typedef struct { + brotli_reg_t val_; + brotli_reg_t bit_pos_; + const uint8_t* next_in; + size_t avail_in; +} BrotliBitReaderState; + +/* Initializes the BrotliBitReader fields. */ +BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* br); + +/* Ensures that accumulator is not empty. + May consume up to sizeof(brotli_reg_t) - 1 bytes of input. + Returns BROTLI_FALSE if data is required but there is no input available. + For !BROTLI_UNALIGNED_READ_FAST this function also prepares bit reader for + aligned reading. */ +BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* br); + +/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden + the main code-path. Never called for RFC brotli streams, required only for + "large-window" mode and other extensions. */ +BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow( + BrotliBitReader* br, brotli_reg_t n_bits, brotli_reg_t* val); + +static BROTLI_INLINE size_t +BrotliBitReaderGetAvailIn(BrotliBitReader* const br) { + return (size_t)(br->last_in - br->next_in); +} + +static BROTLI_INLINE void BrotliBitReaderSaveState( + BrotliBitReader* const from, BrotliBitReaderState* to) { + to->val_ = from->val_; + to->bit_pos_ = from->bit_pos_; + to->next_in = from->next_in; + to->avail_in = BrotliBitReaderGetAvailIn(from); +} + +static BROTLI_INLINE void BrotliBitReaderSetInput( + BrotliBitReader* const br, const uint8_t* next_in, size_t avail_in) { + br->next_in = next_in; + br->last_in = (avail_in == 0) ? next_in : (next_in + avail_in); + if (avail_in + 1 > BROTLI_FAST_INPUT_SLACK) { + br->guard_in = next_in + (avail_in + 1 - BROTLI_FAST_INPUT_SLACK); + } else { + br->guard_in = next_in; + } +} + +static BROTLI_INLINE void BrotliBitReaderRestoreState( + BrotliBitReader* const to, BrotliBitReaderState* from) { + to->val_ = from->val_; + to->bit_pos_ = from->bit_pos_; + to->next_in = from->next_in; + BrotliBitReaderSetInput(to, from->next_in, from->avail_in); +} + +static BROTLI_INLINE brotli_reg_t BrotliGetAvailableBits( + const BrotliBitReader* br) { + return br->bit_pos_; +} + +/* Returns amount of unread bytes the bit reader still has buffered from the + BrotliInput, including whole bytes in br->val_. Result is capped with + maximal ring-buffer size (larger number won't be utilized anyway). */ +static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) { + static const size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS; + size_t avail_in = BrotliBitReaderGetAvailIn(br); + if (avail_in > kCap) return kCap; + return avail_in + (BrotliGetAvailableBits(br) >> 3); +} + +/* Checks if there is at least |num| bytes left in the input ring-buffer + (excluding the bits remaining in br->val_). */ +static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount( + BrotliBitReader* const br) { + return TO_BROTLI_BOOL(br->next_in < br->guard_in); +} + +/* Load more bits into accumulator. */ +static BROTLI_INLINE brotli_reg_t BrotliBitReaderLoadBits(brotli_reg_t val, + brotli_reg_t new_bits, + brotli_reg_t count, + brotli_reg_t offset) { + BROTLI_DCHECK( + !((val >> offset) & ~new_bits & ~(~((brotli_reg_t)0) << count))); + (void)count; + return val | (new_bits << offset); +} + +/* Guarantees that there are at least |n_bits| + 1 bits in accumulator. + Precondition: accumulator contains at least 1 bit. + |n_bits| should be in the range [1..24] for regular build. For portable + non-64-bit little-endian build only 16 bits are safe to request. */ +static BROTLI_INLINE void BrotliFillBitWindow( + BrotliBitReader* const br, brotli_reg_t n_bits) { +#if (BROTLI_64_BITS) + if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) && + (n_bits <= 8)) { + brotli_reg_t bit_pos = br->bit_pos_; + if (bit_pos <= 8) { + br->val_ = BrotliBitReaderLoadBits(br->val_, + BROTLI_UNALIGNED_LOAD64LE(br->next_in), 56, bit_pos); + br->bit_pos_ = bit_pos + 56; + br->next_in += 7; + } + } else if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) && + (n_bits <= 16)) { + brotli_reg_t bit_pos = br->bit_pos_; + if (bit_pos <= 16) { + br->val_ = BrotliBitReaderLoadBits(br->val_, + BROTLI_UNALIGNED_LOAD64LE(br->next_in), 48, bit_pos); + br->bit_pos_ = bit_pos + 48; + br->next_in += 6; + } + } else { + brotli_reg_t bit_pos = br->bit_pos_; + if (bit_pos <= 32) { + br->val_ = BrotliBitReaderLoadBits(br->val_, + (uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in), 32, bit_pos); + br->bit_pos_ = bit_pos + 32; + br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ; + } + } +#else + if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) && + (n_bits <= 8)) { + brotli_reg_t bit_pos = br->bit_pos_; + if (bit_pos <= 8) { + br->val_ = BrotliBitReaderLoadBits(br->val_, + BROTLI_UNALIGNED_LOAD32LE(br->next_in), 24, bit_pos); + br->bit_pos_ = bit_pos + 24; + br->next_in += 3; + } + } else { + brotli_reg_t bit_pos = br->bit_pos_; + if (bit_pos <= 16) { + br->val_ = BrotliBitReaderLoadBits(br->val_, + (uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in), 16, bit_pos); + br->bit_pos_ = bit_pos + 16; + br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ; + } + } +#endif +} + +/* Mostly like BrotliFillBitWindow, but guarantees only 16 bits and reads no + more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */ +static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) { + BrotliFillBitWindow(br, 17); +} + +/* Tries to pull one byte of input to accumulator. + Returns BROTLI_FALSE if there is no input available. */ +static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) { + if (br->next_in == br->last_in) { + return BROTLI_FALSE; + } + br->val_ = BrotliBitReaderLoadBits(br->val_, + (brotli_reg_t)*br->next_in, 8, br->bit_pos_); + br->bit_pos_ += 8; + ++br->next_in; + return BROTLI_TRUE; +} + +/* Returns currently available bits. + The number of valid bits could be calculated by BrotliGetAvailableBits. */ +static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked( + BrotliBitReader* const br) { + return br->val_; +} + +/* Like BrotliGetBits, but does not mask the result. + The result contains at least 16 valid bits. */ +static BROTLI_INLINE brotli_reg_t BrotliGet16BitsUnmasked( + BrotliBitReader* const br) { + BrotliFillBitWindow(br, 16); + return (brotli_reg_t)BrotliGetBitsUnmasked(br); +} + +/* Returns the specified number of bits from |br| without advancing bit + position. */ +static BROTLI_INLINE brotli_reg_t BrotliGetBits( + BrotliBitReader* const br, brotli_reg_t n_bits) { + BrotliFillBitWindow(br, n_bits); + return BrotliGetBitsUnmasked(br) & BitMask(n_bits); +} + +/* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there + is not enough input. */ +static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits( + BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) { + while (BrotliGetAvailableBits(br) < n_bits) { + if (!BrotliPullByte(br)) { + return BROTLI_FALSE; + } + } + *val = BrotliGetBitsUnmasked(br) & BitMask(n_bits); + return BROTLI_TRUE; +} + +/* Advances the bit pos by |n_bits|. */ +static BROTLI_INLINE void BrotliDropBits( + BrotliBitReader* const br, brotli_reg_t n_bits) { + br->bit_pos_ -= n_bits; + br->val_ >>= n_bits; +} + +/* Make sure that there are no spectre bits in accumulator. + This is important for the cases when some bytes are skipped + (i.e. never placed into accumulator). */ +static BROTLI_INLINE void BrotliBitReaderNormalize(BrotliBitReader* br) { + /* Actually, it is enough to normalize when br->bit_pos_ == 0 */ + if (br->bit_pos_ < (sizeof(brotli_reg_t) << 3u)) { + br->val_ &= (((brotli_reg_t)1) << br->bit_pos_) - 1; + } +} + +static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) { + brotli_reg_t unused_bytes = BrotliGetAvailableBits(br) >> 3; + brotli_reg_t unused_bits = unused_bytes << 3; + br->next_in = + (unused_bytes == 0) ? br->next_in : (br->next_in - unused_bytes); + br->bit_pos_ -= unused_bits; + BrotliBitReaderNormalize(br); +} + +/* Reads the specified number of bits from |br| and advances the bit pos. + Precondition: accumulator MUST contain at least |n_bits|. */ +static BROTLI_INLINE void BrotliTakeBits(BrotliBitReader* const br, + brotli_reg_t n_bits, + brotli_reg_t* val) { + *val = BrotliGetBitsUnmasked(br) & BitMask(n_bits); + BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n", + (int)BrotliBitReaderGetAvailIn(br), (int)br->bit_pos_, + (int)n_bits, (int)*val)); + BrotliDropBits(br, n_bits); +} + +/* Reads the specified number of bits from |br| and advances the bit pos. + Assumes that there is enough input to perform BrotliFillBitWindow. + Up to 24 bits are allowed to be requested from this method. */ +static BROTLI_INLINE brotli_reg_t BrotliReadBits24( + BrotliBitReader* const br, brotli_reg_t n_bits) { + BROTLI_DCHECK(n_bits <= 24); + if (BROTLI_64_BITS || (n_bits <= 16)) { + brotli_reg_t val; + BrotliFillBitWindow(br, n_bits); + BrotliTakeBits(br, n_bits, &val); + return val; + } else { + brotli_reg_t low_val; + brotli_reg_t high_val; + BrotliFillBitWindow(br, 16); + BrotliTakeBits(br, 16, &low_val); + BrotliFillBitWindow(br, 8); + BrotliTakeBits(br, n_bits - 16, &high_val); + return low_val | (high_val << 16); + } +} + +/* Same as BrotliReadBits24, but allows reading up to 32 bits. */ +static BROTLI_INLINE brotli_reg_t BrotliReadBits32( + BrotliBitReader* const br, brotli_reg_t n_bits) { + BROTLI_DCHECK(n_bits <= 32); + if (BROTLI_64_BITS || (n_bits <= 16)) { + brotli_reg_t val; + BrotliFillBitWindow(br, n_bits); + BrotliTakeBits(br, n_bits, &val); + return val; + } else { + brotli_reg_t low_val; + brotli_reg_t high_val; + BrotliFillBitWindow(br, 16); + BrotliTakeBits(br, 16, &low_val); + BrotliFillBitWindow(br, 16); + BrotliTakeBits(br, n_bits - 16, &high_val); + return low_val | (high_val << 16); + } +} + +/* Tries to read the specified amount of bits. Returns BROTLI_FALSE, if there + is not enough input. |n_bits| MUST be positive. + Up to 24 bits are allowed to be requested from this method. */ +static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits( + BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) { + BROTLI_DCHECK(n_bits <= 24); + while (BrotliGetAvailableBits(br) < n_bits) { + if (!BrotliPullByte(br)) { + return BROTLI_FALSE; + } + } + BrotliTakeBits(br, n_bits, val); + return BROTLI_TRUE; +} + +/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */ +static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32( + BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) { + BROTLI_DCHECK(n_bits <= 32); + if (BROTLI_64_BITS || (n_bits <= 24)) { + while (BrotliGetAvailableBits(br) < n_bits) { + if (!BrotliPullByte(br)) { + return BROTLI_FALSE; + } + } + BrotliTakeBits(br, n_bits, val); + return BROTLI_TRUE; + } else { + return BrotliSafeReadBits32Slow(br, n_bits, val); + } +} + +/* Advances the bit reader position to the next byte boundary and verifies + that any skipped bits are set to zero. */ +static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) { + brotli_reg_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7; + brotli_reg_t pad_bits = 0; + if (pad_bits_count != 0) { + BrotliTakeBits(br, pad_bits_count, &pad_bits); + } + BrotliBitReaderNormalize(br); + return TO_BROTLI_BOOL(pad_bits == 0); +} + +static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) { + /* Check detour is legal: accumulator must to be empty. */ + BROTLI_DCHECK(br->bit_pos_ == 0); + BROTLI_DCHECK(br->val_ == 0); + br->next_in += num; +} + +/* Copies remaining input bytes stored in the bit reader to the output. Value + |num| may not be larger than BrotliGetRemainingBytes. The bit reader must be + warmed up again after this. */ +static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest, + BrotliBitReader* br, size_t num) { + while (BrotliGetAvailableBits(br) >= 8 && num > 0) { + *dest = (uint8_t)BrotliGetBitsUnmasked(br); + BrotliDropBits(br, 8); + ++dest; + --num; + } + BrotliBitReaderNormalize(br); + if (num > 0) { + memcpy(dest, br->next_in, num); + BrotliDropBytes(br, num); + } +} + +BROTLI_UNUSED_FUNCTION void BrotliBitReaderSuppressUnusedFunctions(void) { + BROTLI_UNUSED(&BrotliBitReaderSuppressUnusedFunctions); + + BROTLI_UNUSED(&BrotliBitReaderGetAvailIn); + BROTLI_UNUSED(&BrotliBitReaderLoadBits); + BROTLI_UNUSED(&BrotliBitReaderRestoreState); + BROTLI_UNUSED(&BrotliBitReaderSaveState); + BROTLI_UNUSED(&BrotliBitReaderSetInput); + BROTLI_UNUSED(&BrotliBitReaderUnload); + BROTLI_UNUSED(&BrotliCheckInputAmount); + BROTLI_UNUSED(&BrotliCopyBytes); + BROTLI_UNUSED(&BrotliFillBitWindow16); + BROTLI_UNUSED(&BrotliGet16BitsUnmasked); + BROTLI_UNUSED(&BrotliGetBits); + BROTLI_UNUSED(&BrotliGetRemainingBytes); + BROTLI_UNUSED(&BrotliJumpToByteBoundary); + BROTLI_UNUSED(&BrotliReadBits24); + BROTLI_UNUSED(&BrotliReadBits32); + BROTLI_UNUSED(&BrotliSafeGetBits); + BROTLI_UNUSED(&BrotliSafeReadBits); + BROTLI_UNUSED(&BrotliSafeReadBits32); +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_BIT_READER_H_ */ diff --git a/packages/runtime/vendor/brotli/c/dec/decode.c b/packages/runtime/vendor/brotli/c/dec/decode.c new file mode 100644 index 000000000..e87e7f5ea --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/decode.c @@ -0,0 +1,2964 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include + +#include "../common/constants.h" +#include "../common/context.h" +#include "../common/dictionary.h" +#include "../common/platform.h" +#include "../common/shared_dictionary_internal.h" +#include "../common/transform.h" +#include "../common/version.h" +#include "bit_reader.h" +#include "huffman.h" +#include "prefix.h" +#include "state.h" +#include "static_init.h" + +#if defined(BROTLI_TARGET_NEON) +#include +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define BROTLI_FAILURE(CODE) (BROTLI_DUMP(), CODE) + +#define BROTLI_LOG_UINT(name) \ + BROTLI_LOG(("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name))) +#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \ + BROTLI_LOG(("[%s] %s[%lu] = %lu\n", __func__, #array_name, \ + (unsigned long)(idx), (unsigned long)array_name[idx])) + +#define HUFFMAN_TABLE_BITS 8U +#define HUFFMAN_TABLE_MASK 0xFF + +/* We need the slack region for the following reasons: + - doing up to two 16-byte copies for fast backward copying + - inserting transformed dictionary word: + 255 prefix + 32 base + 255 suffix */ +static const brotli_reg_t kRingBufferWriteAheadSlack = 542; + +static const BROTLI_MODEL("small") +uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = { + 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, +}; + +/* Static prefix code for the complex code length code lengths. */ +static const BROTLI_MODEL("small") +uint8_t kCodeLengthPrefixLength[16] = { + 2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4, +}; + +static const BROTLI_MODEL("small") +uint8_t kCodeLengthPrefixValue[16] = { + 0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5, +}; + +BROTLI_BOOL BrotliDecoderSetParameter( + BrotliDecoderState* state, BrotliDecoderParameter p, uint32_t value) { + if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE; + switch (p) { + case BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION: + state->canny_ringbuffer_allocation = !!value ? 0 : 1; + return BROTLI_TRUE; + + case BROTLI_DECODER_PARAM_LARGE_WINDOW: + state->large_window = TO_BROTLI_BOOL(!!value); + return BROTLI_TRUE; + + default: return BROTLI_FALSE; + } +} + +BrotliDecoderState* BrotliDecoderCreateInstance( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + BrotliDecoderState* state = 0; + if (!BrotliDecoderEnsureStaticInit()) { + BROTLI_DUMP(); + return 0; + } + if (!alloc_func && !free_func) { + state = (BrotliDecoderState*)malloc(sizeof(BrotliDecoderState)); + } else if (alloc_func && free_func) { + state = (BrotliDecoderState*)alloc_func(opaque, sizeof(BrotliDecoderState)); + } + if (state == 0) { + BROTLI_DUMP(); + return 0; + } + if (!BrotliDecoderStateInit(state, alloc_func, free_func, opaque)) { + BROTLI_DUMP(); + if (!alloc_func && !free_func) { + free(state); + } else if (alloc_func && free_func) { + free_func(opaque, state); + } + return 0; + } + return state; +} + +/* Deinitializes and frees BrotliDecoderState instance. */ +void BrotliDecoderDestroyInstance(BrotliDecoderState* state) { + if (!state) { + return; + } else { + brotli_free_func free_func = state->free_func; + void* opaque = state->memory_manager_opaque; + BrotliDecoderStateCleanup(state); + free_func(opaque, state); + } +} + +/* Saves error code and converts it to BrotliDecoderResult. */ +static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode( + BrotliDecoderState* s, BrotliDecoderErrorCode e, size_t consumed_input) { + s->error_code = (int)e; + s->used_input += consumed_input; + if ((s->buffer_length != 0) && (s->br.next_in == s->br.last_in)) { + /* If internal buffer is depleted at last, reset it. */ + s->buffer_length = 0; + } + switch (e) { + case BROTLI_DECODER_SUCCESS: + return BROTLI_DECODER_RESULT_SUCCESS; + + case BROTLI_DECODER_NEEDS_MORE_INPUT: + return BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT; + + case BROTLI_DECODER_NEEDS_MORE_OUTPUT: + return BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT; + + default: + return BROTLI_DECODER_RESULT_ERROR; + } +} + +/* Decodes WBITS by reading 1 - 7 bits, or 0x11 for "Large Window Brotli". + Precondition: bit-reader accumulator has at least 8 bits. */ +static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s, + BrotliBitReader* br) { + brotli_reg_t n; + BROTLI_BOOL large_window = s->large_window; + s->large_window = BROTLI_FALSE; + BrotliTakeBits(br, 1, &n); + if (n == 0) { + s->window_bits = 16; + return BROTLI_DECODER_SUCCESS; + } + BrotliTakeBits(br, 3, &n); + if (n != 0) { + s->window_bits = (17u + n) & 63u; + return BROTLI_DECODER_SUCCESS; + } + BrotliTakeBits(br, 3, &n); + if (n == 1) { + if (large_window) { + BrotliTakeBits(br, 1, &n); + if (n == 1) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS); + } + s->large_window = BROTLI_TRUE; + return BROTLI_DECODER_SUCCESS; + } else { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS); + } + } + if (n != 0) { + s->window_bits = (8u + n) & 63u; + return BROTLI_DECODER_SUCCESS; + } + s->window_bits = 17; + return BROTLI_DECODER_SUCCESS; +} + +static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) { +#if defined(BROTLI_TARGET_NEON) + vst1q_u8(dst, vld1q_u8(src)); +#else + uint32_t buffer[4]; + memcpy(buffer, src, 16); + memcpy(dst, buffer, 16); +#endif +} + +/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */ +static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8( + BrotliDecoderState* s, BrotliBitReader* br, brotli_reg_t* value) { + brotli_reg_t bits; + switch (s->substate_decode_uint8) { + case BROTLI_STATE_DECODE_UINT8_NONE: + if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (bits == 0) { + *value = 0; + return BROTLI_DECODER_SUCCESS; + } + /* Fall through. */ + + case BROTLI_STATE_DECODE_UINT8_SHORT: + if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 3, &bits))) { + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_SHORT; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (bits == 0) { + *value = 1; + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE; + return BROTLI_DECODER_SUCCESS; + } + /* Use output value as a temporary storage. It MUST be persisted. */ + *value = bits; + /* Fall through. */ + + case BROTLI_STATE_DECODE_UINT8_LONG: + if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, *value, &bits))) { + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_LONG; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + *value = ((brotli_reg_t)1U << *value) + bits; + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE; + return BROTLI_DECODER_SUCCESS; + + default: + return + BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */ + } +} + +/* Decodes a metablock length and flags by reading 2 - 31 bits. */ +static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength( + BrotliDecoderState* s, BrotliBitReader* br) { + brotli_reg_t bits; + int i; + for (;;) { + switch (s->substate_metablock_header) { + case BROTLI_STATE_METABLOCK_HEADER_NONE: + if (!BrotliSafeReadBits(br, 1, &bits)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + s->is_last_metablock = bits ? 1 : 0; + s->meta_block_remaining_len = 0; + s->is_uncompressed = 0; + s->is_metadata = 0; + if (!s->is_last_metablock) { + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES; + break; + } + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_EMPTY; + /* Fall through. */ + + case BROTLI_STATE_METABLOCK_HEADER_EMPTY: + if (!BrotliSafeReadBits(br, 1, &bits)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (bits) { + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + return BROTLI_DECODER_SUCCESS; + } + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NIBBLES; + /* Fall through. */ + + case BROTLI_STATE_METABLOCK_HEADER_NIBBLES: + if (!BrotliSafeReadBits(br, 2, &bits)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + s->size_nibbles = (uint8_t)(bits + 4); + s->loop_counter = 0; + if (bits == 3) { + s->is_metadata = 1; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_RESERVED; + break; + } + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_SIZE; + /* Fall through. */ + + case BROTLI_STATE_METABLOCK_HEADER_SIZE: + i = s->loop_counter; + for (; i < (int)s->size_nibbles; ++i) { + if (!BrotliSafeReadBits(br, 4, &bits)) { + s->loop_counter = i; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (i + 1 == (int)s->size_nibbles && s->size_nibbles > 4 && + bits == 0) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_NIBBLE); + } + s->meta_block_remaining_len |= (int)(bits << (i * 4)); + } + s->substate_metablock_header = + BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED; + /* Fall through. */ + + case BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED: + if (!s->is_last_metablock) { + if (!BrotliSafeReadBits(br, 1, &bits)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + s->is_uncompressed = bits ? 1 : 0; + } + ++s->meta_block_remaining_len; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + return BROTLI_DECODER_SUCCESS; + + case BROTLI_STATE_METABLOCK_HEADER_RESERVED: + if (!BrotliSafeReadBits(br, 1, &bits)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (bits != 0) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_RESERVED); + } + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_BYTES; + /* Fall through. */ + + case BROTLI_STATE_METABLOCK_HEADER_BYTES: + if (!BrotliSafeReadBits(br, 2, &bits)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (bits == 0) { + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + return BROTLI_DECODER_SUCCESS; + } + s->size_nibbles = (uint8_t)bits; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_METADATA; + /* Fall through. */ + + case BROTLI_STATE_METABLOCK_HEADER_METADATA: + i = s->loop_counter; + for (; i < (int)s->size_nibbles; ++i) { + if (!BrotliSafeReadBits(br, 8, &bits)) { + s->loop_counter = i; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (i + 1 == (int)s->size_nibbles && s->size_nibbles > 1 && + bits == 0) { + return BROTLI_FAILURE( + BROTLI_DECODER_ERROR_FORMAT_EXUBERANT_META_NIBBLE); + } + s->meta_block_remaining_len |= (int)(bits << (i * 8)); + } + ++s->meta_block_remaining_len; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + return BROTLI_DECODER_SUCCESS; + + default: + return + BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */ + } + } +} + +/* Decodes the Huffman code. + This method doesn't read data from the bit reader, BUT drops the amount of + bits that correspond to the decoded symbol. + bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */ +static BROTLI_INLINE brotli_reg_t DecodeSymbol(brotli_reg_t bits, + const HuffmanCode* table, + BrotliBitReader* br) { + BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table); + BROTLI_HC_ADJUST_TABLE_INDEX(table, bits & HUFFMAN_TABLE_MASK); + if (BROTLI_HC_FAST_LOAD_BITS(table) > HUFFMAN_TABLE_BITS) { + brotli_reg_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS; + BrotliDropBits(br, HUFFMAN_TABLE_BITS); + BROTLI_HC_ADJUST_TABLE_INDEX(table, + BROTLI_HC_FAST_LOAD_VALUE(table) + + ((bits >> HUFFMAN_TABLE_BITS) & BitMask(nbits))); + } + BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(table)); + return BROTLI_HC_FAST_LOAD_VALUE(table); +} + +/* Reads and decodes the next Huffman code from bit-stream. + This method peeks 16 bits of input and drops 0 - 15 of them. */ +static BROTLI_INLINE brotli_reg_t ReadSymbol(const HuffmanCode* table, + BrotliBitReader* br) { + return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br); +} + +/* Same as DecodeSymbol, but it is known that there is less than 15 bits of + input are currently available. */ +static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol( + const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) { + brotli_reg_t val; + brotli_reg_t available_bits = BrotliGetAvailableBits(br); + BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table); + if (available_bits == 0) { + if (BROTLI_HC_FAST_LOAD_BITS(table) == 0) { + *result = BROTLI_HC_FAST_LOAD_VALUE(table); + return BROTLI_TRUE; + } + return BROTLI_FALSE; /* No valid bits at all. */ + } + val = BrotliGetBitsUnmasked(br); + BROTLI_HC_ADJUST_TABLE_INDEX(table, val & HUFFMAN_TABLE_MASK); + if (BROTLI_HC_FAST_LOAD_BITS(table) <= HUFFMAN_TABLE_BITS) { + if (BROTLI_HC_FAST_LOAD_BITS(table) <= available_bits) { + BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(table)); + *result = BROTLI_HC_FAST_LOAD_VALUE(table); + return BROTLI_TRUE; + } else { + return BROTLI_FALSE; /* Not enough bits for the first level. */ + } + } + if (available_bits <= HUFFMAN_TABLE_BITS) { + return BROTLI_FALSE; /* Not enough bits to move to the second level. */ + } + + /* Speculatively drop HUFFMAN_TABLE_BITS. */ + val = (val & BitMask(BROTLI_HC_FAST_LOAD_BITS(table))) >> HUFFMAN_TABLE_BITS; + available_bits -= HUFFMAN_TABLE_BITS; + BROTLI_HC_ADJUST_TABLE_INDEX(table, BROTLI_HC_FAST_LOAD_VALUE(table) + val); + if (available_bits < BROTLI_HC_FAST_LOAD_BITS(table)) { + return BROTLI_FALSE; /* Not enough bits for the second level. */ + } + + BrotliDropBits(br, HUFFMAN_TABLE_BITS + BROTLI_HC_FAST_LOAD_BITS(table)); + *result = BROTLI_HC_FAST_LOAD_VALUE(table); + return BROTLI_TRUE; +} + +static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol( + const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) { + brotli_reg_t val; + if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) { + *result = DecodeSymbol(val, table, br); + return BROTLI_TRUE; + } + return SafeDecodeSymbol(table, br, result); +} + +/* Makes a look-up in first level Huffman table. Peeks 8 bits. */ +static BROTLI_INLINE void PreloadSymbol(int safe, + const HuffmanCode* table, + BrotliBitReader* br, + brotli_reg_t* bits, + brotli_reg_t* value) { + if (safe) { + return; + } + BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table); + BROTLI_HC_ADJUST_TABLE_INDEX(table, BrotliGetBits(br, HUFFMAN_TABLE_BITS)); + *bits = BROTLI_HC_FAST_LOAD_BITS(table); + *value = BROTLI_HC_FAST_LOAD_VALUE(table); +} + +/* Decodes the next Huffman code using data prepared by PreloadSymbol. + Reads 0 - 15 bits. Also peeks 8 following bits. */ +static BROTLI_INLINE brotli_reg_t ReadPreloadedSymbol(const HuffmanCode* table, + BrotliBitReader* br, + brotli_reg_t* bits, + brotli_reg_t* value) { + brotli_reg_t result = *value; + if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) { + brotli_reg_t val = BrotliGet16BitsUnmasked(br); + const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value; + brotli_reg_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS)); + BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(ext); + BrotliDropBits(br, HUFFMAN_TABLE_BITS); + BROTLI_HC_ADJUST_TABLE_INDEX(ext, (val >> HUFFMAN_TABLE_BITS) & mask); + BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(ext)); + result = BROTLI_HC_FAST_LOAD_VALUE(ext); + } else { + BrotliDropBits(br, *bits); + } + PreloadSymbol(0, table, br, bits, value); + return result; +} + +/* Reads up to limit symbols from br and copies them into ringbuffer, + starting from pos. Caller must ensure that there is enough space + for the write. Returns the amount of symbols actually copied. */ +static BROTLI_INLINE int BrotliCopyPreloadedSymbolsToU8(const HuffmanCode* table, + BrotliBitReader* br, + brotli_reg_t* bits, + brotli_reg_t* value, + uint8_t* ringbuffer, + int pos, + const int limit) { + /* Calculate range where CheckInputAmount is always true. + Start with the number of bytes we can read. */ + int64_t new_lim = br->guard_in - br->next_in; + /* Convert to bits, since symbols use variable number of bits. */ + new_lim *= 8; + /* At most 15 bits per symbol, so this is safe. */ + new_lim /= 15; + const int kMaximalOverread = 4; + int pos_limit = limit; + int copies = 0; + if ((new_lim - kMaximalOverread) <= limit) { + // Safe cast, since new_lim is already < num_steps + pos_limit = (int)(new_lim - kMaximalOverread); + } + if (pos_limit < 0) { + pos_limit = 0; + } + copies = pos_limit; + pos_limit += pos; + /* Fast path, caller made sure it is safe to write, + we verified that is is safe to read. */ + for (; pos < pos_limit; pos++) { + BROTLI_DCHECK(BrotliCheckInputAmount(br)); + ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(table, br, bits, value); + BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos); + } + /* Do the remainder, caller made sure it is safe to write, + we need to bverify that it is safe to read. */ + while (BrotliCheckInputAmount(br) && copies < limit) { + ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(table, br, bits, value); + BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos); + pos++; + copies++; + } + return copies; +} + +static BROTLI_INLINE brotli_reg_t Log2Floor(brotli_reg_t x) { + brotli_reg_t result = 0; + while (x) { + x >>= 1; + ++result; + } + return result; +} + +/* Reads (s->symbol + 1) symbols. + Totally 1..4 symbols are read, 1..11 bits each. + The list of symbols MUST NOT contain duplicates. */ +static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols( + brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit, + BrotliDecoderState* s) { + /* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */ + BrotliBitReader* br = &s->br; + BrotliMetablockHeaderArena* h = &s->arena.header; + brotli_reg_t max_bits = Log2Floor(alphabet_size_max - 1); + brotli_reg_t i = h->sub_loop_counter; + brotli_reg_t num_symbols = h->symbol; + while (i <= num_symbols) { + brotli_reg_t v; + if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) { + h->sub_loop_counter = i; + h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (v >= alphabet_size_limit) { + return + BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET); + } + h->symbols_lists_array[i] = (uint16_t)v; + BROTLI_LOG_UINT(h->symbols_lists_array[i]); + ++i; + } + + for (i = 0; i < num_symbols; ++i) { + brotli_reg_t k = i + 1; + for (; k <= num_symbols; ++k) { + if (h->symbols_lists_array[i] == h->symbols_lists_array[k]) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME); + } + } + } + + return BROTLI_DECODER_SUCCESS; +} + +/* Process single decoded symbol code length: + A) reset the repeat variable + B) remember code length (if it is not 0) + C) extend corresponding index-chain + D) reduce the Huffman space + E) update the histogram */ +static BROTLI_INLINE void ProcessSingleCodeLength(brotli_reg_t code_len, + brotli_reg_t* symbol, brotli_reg_t* repeat, brotli_reg_t* space, + brotli_reg_t* prev_code_len, uint16_t* symbol_lists, + uint16_t* code_length_histo, int* next_symbol) { + *repeat = 0; + if (code_len != 0) { /* code_len == 1..15 */ + symbol_lists[next_symbol[code_len]] = (uint16_t)(*symbol); + next_symbol[code_len] = (int)(*symbol); + *prev_code_len = code_len; + *space -= 32768U >> code_len; + code_length_histo[code_len]++; + BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n", + (int)*symbol, (int)code_len)); + } + (*symbol)++; +} + +/* Process repeated symbol code length. + A) Check if it is the extension of previous repeat sequence; if the decoded + value is not BROTLI_REPEAT_PREVIOUS_CODE_LENGTH, then it is a new + symbol-skip + B) Update repeat variable + C) Check if operation is feasible (fits alphabet) + D) For each symbol do the same operations as in ProcessSingleCodeLength + + PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or + code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */ +static BROTLI_INLINE void ProcessRepeatedCodeLength(brotli_reg_t code_len, + brotli_reg_t repeat_delta, brotli_reg_t alphabet_size, brotli_reg_t* symbol, + brotli_reg_t* repeat, brotli_reg_t* space, brotli_reg_t* prev_code_len, + brotli_reg_t* repeat_code_len, uint16_t* symbol_lists, + uint16_t* code_length_histo, int* next_symbol) { + brotli_reg_t old_repeat; + brotli_reg_t extra_bits = 3; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ + brotli_reg_t new_len = 0; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ + if (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) { + new_len = *prev_code_len; + extra_bits = 2; + } + if (*repeat_code_len != new_len) { + *repeat = 0; + *repeat_code_len = new_len; + } + old_repeat = *repeat; + if (*repeat > 0) { + *repeat -= 2; + *repeat <<= extra_bits; + } + *repeat += repeat_delta + 3U; + repeat_delta = *repeat - old_repeat; + if (*symbol + repeat_delta > alphabet_size) { + BROTLI_DUMP(); + *symbol = alphabet_size; + *space = 0xFFFFF; + return; + } + BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n", + (int)*symbol, (int)(*symbol + repeat_delta - 1), (int)*repeat_code_len)); + if (*repeat_code_len != 0) { + brotli_reg_t last = *symbol + repeat_delta; + int next = next_symbol[*repeat_code_len]; + do { + symbol_lists[next] = (uint16_t)*symbol; + next = (int)*symbol; + } while (++(*symbol) != last); + next_symbol[*repeat_code_len] = next; + *space -= repeat_delta << (15 - *repeat_code_len); + code_length_histo[*repeat_code_len] = + (uint16_t)(code_length_histo[*repeat_code_len] + repeat_delta); + } else { + *symbol += repeat_delta; + } +} + +/* Reads and decodes symbol codelengths. */ +static BrotliDecoderErrorCode ReadSymbolCodeLengths( + brotli_reg_t alphabet_size, BrotliDecoderState* s) { + BrotliBitReader* br = &s->br; + BrotliMetablockHeaderArena* h = &s->arena.header; + brotli_reg_t symbol = h->symbol; + brotli_reg_t repeat = h->repeat; + brotli_reg_t space = h->space; + brotli_reg_t prev_code_len = h->prev_code_len; + brotli_reg_t repeat_code_len = h->repeat_code_len; + uint16_t* symbol_lists = h->symbol_lists; + uint16_t* code_length_histo = h->code_length_histo; + int* next_symbol = h->next_symbol; + if (!BrotliWarmupBitReader(br)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + while (symbol < alphabet_size && space > 0) { + const HuffmanCode* p = h->table; + brotli_reg_t code_len; + BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p); + if (!BrotliCheckInputAmount(br)) { + h->symbol = symbol; + h->repeat = repeat; + h->prev_code_len = prev_code_len; + h->repeat_code_len = repeat_code_len; + h->space = space; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + BrotliFillBitWindow16(br); + BROTLI_HC_ADJUST_TABLE_INDEX(p, BrotliGetBitsUnmasked(br) & + BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH)); + BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p)); /* Use 1..5 bits. */ + code_len = BROTLI_HC_FAST_LOAD_VALUE(p); /* code_len == 0..17 */ + if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) { + ProcessSingleCodeLength(code_len, &symbol, &repeat, &space, + &prev_code_len, symbol_lists, code_length_histo, next_symbol); + } else { /* code_len == 16..17, extra_bits == 2..3 */ + brotli_reg_t extra_bits = + (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3; + brotli_reg_t repeat_delta = + BrotliGetBitsUnmasked(br) & BitMask(extra_bits); + BrotliDropBits(br, extra_bits); + ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size, + &symbol, &repeat, &space, &prev_code_len, &repeat_code_len, + symbol_lists, code_length_histo, next_symbol); + } + } + h->space = space; + return BROTLI_DECODER_SUCCESS; +} + +static BrotliDecoderErrorCode SafeReadSymbolCodeLengths( + brotli_reg_t alphabet_size, BrotliDecoderState* s) { + BrotliBitReader* br = &s->br; + BrotliMetablockHeaderArena* h = &s->arena.header; + BROTLI_BOOL get_byte = BROTLI_FALSE; + while (h->symbol < alphabet_size && h->space > 0) { + const HuffmanCode* p = h->table; + brotli_reg_t code_len; + brotli_reg_t available_bits; + brotli_reg_t bits = 0; + BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p); + if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT; + get_byte = BROTLI_FALSE; + available_bits = BrotliGetAvailableBits(br); + if (available_bits != 0) { + bits = (uint32_t)BrotliGetBitsUnmasked(br); + } + BROTLI_HC_ADJUST_TABLE_INDEX(p, + bits & BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH)); + if (BROTLI_HC_FAST_LOAD_BITS(p) > available_bits) { + get_byte = BROTLI_TRUE; + continue; + } + code_len = BROTLI_HC_FAST_LOAD_VALUE(p); /* code_len == 0..17 */ + if (code_len < BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) { + BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p)); + ProcessSingleCodeLength(code_len, &h->symbol, &h->repeat, &h->space, + &h->prev_code_len, h->symbol_lists, h->code_length_histo, + h->next_symbol); + } else { /* code_len == 16..17, extra_bits == 2..3 */ + brotli_reg_t extra_bits = code_len - 14U; + brotli_reg_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) & + BitMask(extra_bits); + if (available_bits < BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits) { + get_byte = BROTLI_TRUE; + continue; + } + BrotliDropBits(br, BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits); + ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size, + &h->symbol, &h->repeat, &h->space, &h->prev_code_len, + &h->repeat_code_len, h->symbol_lists, h->code_length_histo, + h->next_symbol); + } + } + return BROTLI_DECODER_SUCCESS; +} + +/* Reads and decodes 15..18 codes using static prefix code. + Each code is 2..4 bits long. In total 30..72 bits are used. */ +static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) { + BrotliBitReader* br = &s->br; + BrotliMetablockHeaderArena* h = &s->arena.header; + brotli_reg_t num_codes = h->repeat; + brotli_reg_t space = h->space; + brotli_reg_t i = h->sub_loop_counter; + for (; i < BROTLI_CODE_LENGTH_CODES; ++i) { + const uint8_t code_len_idx = kCodeLengthCodeOrder[i]; + brotli_reg_t ix; + brotli_reg_t v; + if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) { + brotli_reg_t available_bits = BrotliGetAvailableBits(br); + if (available_bits != 0) { + ix = BrotliGetBitsUnmasked(br) & 0xF; + } else { + ix = 0; + } + if (kCodeLengthPrefixLength[ix] > available_bits) { + h->sub_loop_counter = i; + h->repeat = num_codes; + h->space = space; + h->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + } + v = kCodeLengthPrefixValue[ix]; + BrotliDropBits(br, kCodeLengthPrefixLength[ix]); + h->code_length_code_lengths[code_len_idx] = (uint8_t)v; + BROTLI_LOG_ARRAY_INDEX(h->code_length_code_lengths, code_len_idx); + if (v != 0) { + space = space - (32U >> v); + ++num_codes; + ++h->code_length_histo[v]; + if (space - 1U >= 32U) { + /* space is 0 or wrapped around. */ + break; + } + } + } + if (!(num_codes == 1 || space == 0)) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_CL_SPACE); + } + return BROTLI_DECODER_SUCCESS; +} + +/* Decodes the Huffman tables. + There are 2 scenarios: + A) Huffman code contains only few symbols (1..4). Those symbols are read + directly; their code lengths are defined by the number of symbols. + For this scenario 4 - 49 bits will be read. + + B) 2-phase decoding: + B.1) Small Huffman table is decoded; it is specified with code lengths + encoded with predefined entropy code. 32 - 74 bits are used. + B.2) Decoded table is used to decode code lengths of symbols in resulting + Huffman table. In worst case 3520 bits are read. */ +static BrotliDecoderErrorCode ReadHuffmanCode(brotli_reg_t alphabet_size_max, + brotli_reg_t alphabet_size_limit, + HuffmanCode* table, + brotli_reg_t* opt_table_size, + BrotliDecoderState* s) { + BrotliBitReader* br = &s->br; + BrotliMetablockHeaderArena* h = &s->arena.header; + /* State machine. */ + for (;;) { + switch (h->substate_huffman) { + case BROTLI_STATE_HUFFMAN_NONE: + if (!BrotliSafeReadBits(br, 2, &h->sub_loop_counter)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + BROTLI_LOG_UINT(h->sub_loop_counter); + /* The value is used as follows: + 1 for simple code; + 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ + if (h->sub_loop_counter != 1) { + h->space = 32; + h->repeat = 0; /* num_codes */ + memset(&h->code_length_histo[0], 0, sizeof(h->code_length_histo[0]) * + (BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1)); + memset(&h->code_length_code_lengths[0], 0, + sizeof(h->code_length_code_lengths)); + h->substate_huffman = BROTLI_STATE_HUFFMAN_COMPLEX; + continue; + } + /* Fall through. */ + + case BROTLI_STATE_HUFFMAN_SIMPLE_SIZE: + /* Read symbols, codes & code lengths directly. */ + if (!BrotliSafeReadBits(br, 2, &h->symbol)) { /* num_symbols */ + h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_SIZE; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + h->sub_loop_counter = 0; + /* Fall through. */ + + case BROTLI_STATE_HUFFMAN_SIMPLE_READ: { + BrotliDecoderErrorCode result = + ReadSimpleHuffmanSymbols(alphabet_size_max, alphabet_size_limit, s); + if (result != BROTLI_DECODER_SUCCESS) { + return result; + } + } + /* Fall through. */ + + case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: { + brotli_reg_t table_size; + if (h->symbol == 3) { + brotli_reg_t bits; + if (!BrotliSafeReadBits(br, 1, &bits)) { + h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + h->symbol += bits; + } + BROTLI_LOG_UINT(h->symbol); + table_size = BrotliBuildSimpleHuffmanTable(table, HUFFMAN_TABLE_BITS, + h->symbols_lists_array, + (uint32_t)h->symbol); + if (opt_table_size) { + *opt_table_size = table_size; + } + h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE; + return BROTLI_DECODER_SUCCESS; + } + + /* Decode Huffman-coded code lengths. */ + case BROTLI_STATE_HUFFMAN_COMPLEX: { + brotli_reg_t i; + BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s); + if (result != BROTLI_DECODER_SUCCESS) { + return result; + } + BrotliBuildCodeLengthsHuffmanTable(h->table, + h->code_length_code_lengths, + h->code_length_histo); + memset(&h->code_length_histo[0], 0, sizeof(h->code_length_histo)); + for (i = 0; i <= BROTLI_HUFFMAN_MAX_CODE_LENGTH; ++i) { + h->next_symbol[i] = (int)i - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1); + h->symbol_lists[h->next_symbol[i]] = 0xFFFF; + } + + h->symbol = 0; + h->prev_code_len = BROTLI_INITIAL_REPEATED_CODE_LENGTH; + h->repeat = 0; + h->repeat_code_len = 0; + h->space = 32768; + h->substate_huffman = BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS; + } + /* Fall through. */ + + case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: { + brotli_reg_t table_size; + BrotliDecoderErrorCode result = ReadSymbolCodeLengths( + alphabet_size_limit, s); + if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) { + result = SafeReadSymbolCodeLengths(alphabet_size_limit, s); + } + if (result != BROTLI_DECODER_SUCCESS) { + return result; + } + + if (h->space != 0) { + BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", (int)h->space)); + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_HUFFMAN_SPACE); + } + table_size = BrotliBuildHuffmanTable( + table, HUFFMAN_TABLE_BITS, h->symbol_lists, h->code_length_histo); + if (opt_table_size) { + *opt_table_size = table_size; + } + h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE; + return BROTLI_DECODER_SUCCESS; + } + + default: + return + BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */ + } + } +} + +/* Decodes a block length by reading 3..39 bits. */ +static BROTLI_INLINE brotli_reg_t ReadBlockLength(const HuffmanCode* table, + BrotliBitReader* br) { + brotli_reg_t code; + brotli_reg_t nbits; + code = ReadSymbol(table, br); + nbits = _kBrotliPrefixCodeRanges[code].nbits; /* nbits == 2..24 */ + return _kBrotliPrefixCodeRanges[code].offset + BrotliReadBits24(br, nbits); +} + +/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then + reading can't be continued with ReadBlockLength. */ +static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength( + BrotliDecoderState* s, brotli_reg_t* result, const HuffmanCode* table, + BrotliBitReader* br) { + brotli_reg_t index; + if (s->substate_read_block_length == BROTLI_STATE_READ_BLOCK_LENGTH_NONE) { + if (!SafeReadSymbol(table, br, &index)) { + return BROTLI_FALSE; + } + } else { + index = s->block_length_index; + } + { + brotli_reg_t bits; + brotli_reg_t nbits = _kBrotliPrefixCodeRanges[index].nbits; + brotli_reg_t offset = _kBrotliPrefixCodeRanges[index].offset; + if (!BrotliSafeReadBits(br, nbits, &bits)) { + s->block_length_index = index; + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX; + return BROTLI_FALSE; + } + *result = offset + bits; + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; + return BROTLI_TRUE; + } +} + +/* Transform: + 1) initialize list L with values 0, 1,... 255 + 2) For each input element X: + 2.1) let Y = L[X] + 2.2) remove X-th element from L + 2.3) prepend Y to L + 2.4) append Y to output + + In most cases max(Y) <= 7, so most of L remains intact. + To reduce the cost of initialization, we reuse L, remember the upper bound + of Y values, and reinitialize only first elements in L. + + Most of input values are 0 and 1. To reduce number of branches, we replace + inner for loop with do-while. */ +static BROTLI_NOINLINE void InverseMoveToFrontTransform( + uint8_t* v, brotli_reg_t v_len, BrotliDecoderState* state) { + /* Reinitialize elements that could have been changed. */ + brotli_reg_t i = 1; + brotli_reg_t upper_bound = state->mtf_upper_bound; + uint32_t* mtf = &state->mtf[1]; /* Make mtf[-1] addressable. */ + uint8_t* mtf_u8 = (uint8_t*)mtf; + /* Load endian-aware constant. */ + const uint8_t b0123[4] = {0, 1, 2, 3}; + uint32_t pattern; + memcpy(&pattern, &b0123, 4); + + /* Initialize list using 4 consequent values pattern. */ + mtf[0] = pattern; + do { + pattern += 0x04040404; /* Advance all 4 values by 4. */ + mtf[i] = pattern; + i++; + } while (i <= upper_bound); + + /* Transform the input. */ + upper_bound = 0; + for (i = 0; i < v_len; ++i) { + int index = v[i]; + uint8_t value = mtf_u8[index]; + upper_bound |= v[i]; + v[i] = value; + mtf_u8[-1] = value; + do { + index--; + mtf_u8[index + 1] = mtf_u8[index]; + } while (index >= 0); + } + /* Remember amount of elements to be reinitialized. */ + state->mtf_upper_bound = upper_bound >> 2; +} + +/* Decodes a series of Huffman table using ReadHuffmanCode function. */ +static BrotliDecoderErrorCode HuffmanTreeGroupDecode( + HuffmanTreeGroup* group, BrotliDecoderState* s) { + BrotliMetablockHeaderArena* h = &s->arena.header; + if (h->substate_tree_group != BROTLI_STATE_TREE_GROUP_LOOP) { + h->next = group->codes; + h->htree_index = 0; + h->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP; + } + while (h->htree_index < group->num_htrees) { + brotli_reg_t table_size; + BrotliDecoderErrorCode result = ReadHuffmanCode(group->alphabet_size_max, + group->alphabet_size_limit, h->next, &table_size, s); + if (result != BROTLI_DECODER_SUCCESS) return result; + group->htrees[h->htree_index] = h->next; + h->next += table_size; + ++h->htree_index; + } + h->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE; + return BROTLI_DECODER_SUCCESS; +} + +/* Decodes a context map. + Decoding is done in 4 phases: + 1) Read auxiliary information (6..16 bits) and allocate memory. + In case of trivial context map, decoding is finished at this phase. + 2) Decode Huffman table using ReadHuffmanCode function. + This table will be used for reading context map items. + 3) Read context map items; "0" values could be run-length encoded. + 4) Optionally, apply InverseMoveToFront transform to the resulting map. */ +static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size, + brotli_reg_t* num_htrees, + uint8_t** context_map_arg, + BrotliDecoderState* s) { + BrotliBitReader* br = &s->br; + BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS; + BrotliMetablockHeaderArena* h = &s->arena.header; + + switch ((int)h->substate_context_map) { + case BROTLI_STATE_CONTEXT_MAP_NONE: + result = DecodeVarLenUint8(s, br, num_htrees); + if (result != BROTLI_DECODER_SUCCESS) { + return result; + } + (*num_htrees)++; + h->context_index = 0; + BROTLI_LOG_UINT(context_map_size); + BROTLI_LOG_UINT(*num_htrees); + *context_map_arg = + (uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)context_map_size); + if (*context_map_arg == 0) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MAP); + } + if (*num_htrees <= 1) { + memset(*context_map_arg, 0, (size_t)context_map_size); + return BROTLI_DECODER_SUCCESS; + } + h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_READ_PREFIX; + /* Fall through. */ + + case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: { + brotli_reg_t bits; + /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe + to peek 4 bits ahead. */ + if (!BrotliSafeGetBits(br, 5, &bits)) { + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if ((bits & 1) != 0) { /* Use RLE for zeros. */ + h->max_run_length_prefix = (bits >> 1) + 1; + BrotliDropBits(br, 5); + } else { + h->max_run_length_prefix = 0; + BrotliDropBits(br, 1); + } + BROTLI_LOG_UINT(h->max_run_length_prefix); + h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_HUFFMAN; + } + /* Fall through. */ + + case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: { + brotli_reg_t alphabet_size = *num_htrees + h->max_run_length_prefix; + result = ReadHuffmanCode(alphabet_size, alphabet_size, + h->context_map_table, NULL, s); + if (result != BROTLI_DECODER_SUCCESS) return result; + h->code = 0xFFFF; + h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_DECODE; + } + /* Fall through. */ + + case BROTLI_STATE_CONTEXT_MAP_DECODE: { + brotli_reg_t context_index = h->context_index; + brotli_reg_t max_run_length_prefix = h->max_run_length_prefix; + uint8_t* context_map = *context_map_arg; + brotli_reg_t code = h->code; + BROTLI_BOOL skip_preamble = (code != 0xFFFF); + while (context_index < context_map_size || skip_preamble) { + if (!skip_preamble) { + if (!SafeReadSymbol(h->context_map_table, br, &code)) { + h->code = 0xFFFF; + h->context_index = context_index; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + BROTLI_LOG_UINT(code); + + if (code == 0) { + context_map[context_index++] = 0; + continue; + } + if (code > max_run_length_prefix) { + context_map[context_index++] = + (uint8_t)(code - max_run_length_prefix); + continue; + } + } else { + skip_preamble = BROTLI_FALSE; + } + /* RLE sub-stage. */ + { + brotli_reg_t reps; + if (!BrotliSafeReadBits(br, code, &reps)) { + h->code = code; + h->context_index = context_index; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + reps += (brotli_reg_t)1U << code; + BROTLI_LOG_UINT(reps); + if (context_index + reps > context_map_size) { + return + BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_CONTEXT_MAP_REPEAT); + } + do { + context_map[context_index++] = 0; + } while (--reps); + } + } + } + /* Fall through. */ + + case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: { + brotli_reg_t bits; + if (!BrotliSafeReadBits(br, 1, &bits)) { + h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + if (bits != 0) { + InverseMoveToFrontTransform(*context_map_arg, context_map_size, s); + } + h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE; + return BROTLI_DECODER_SUCCESS; + } + + default: + return + BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */ + } +} + +/* Decodes a command or literal and updates block type ring-buffer. + Reads 3..54 bits. */ +static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength( + int safe, BrotliDecoderState* s, int tree_type) { + brotli_reg_t max_block_type = s->num_block_types[tree_type]; + const HuffmanCode* type_tree = &s->block_type_trees[ + tree_type * BROTLI_HUFFMAN_MAX_SIZE_258]; + const HuffmanCode* len_tree = &s->block_len_trees[ + tree_type * BROTLI_HUFFMAN_MAX_SIZE_26]; + BrotliBitReader* br = &s->br; + brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2]; + brotli_reg_t block_type; + if (max_block_type <= 1) { + return BROTLI_FALSE; + } + + /* Read 0..15 + 3..39 bits. */ + if (!safe) { + block_type = ReadSymbol(type_tree, br); + s->block_length[tree_type] = ReadBlockLength(len_tree, br); + } else { + BrotliBitReaderState memento; + BrotliBitReaderSaveState(br, &memento); + if (!SafeReadSymbol(type_tree, br, &block_type)) return BROTLI_FALSE; + if (!SafeReadBlockLength(s, &s->block_length[tree_type], len_tree, br)) { + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; + BrotliBitReaderRestoreState(br, &memento); + return BROTLI_FALSE; + } + } + + if (block_type == 1) { + block_type = ringbuffer[1] + 1; + } else if (block_type == 0) { + block_type = ringbuffer[0]; + } else { + block_type -= 2; + } + if (block_type >= max_block_type) { + block_type -= max_block_type; + } + ringbuffer[0] = ringbuffer[1]; + ringbuffer[1] = block_type; + return BROTLI_TRUE; +} + +static BROTLI_INLINE void DetectTrivialLiteralBlockTypes( + BrotliDecoderState* s) { + size_t i; + for (i = 0; i < 8; ++i) s->trivial_literal_contexts[i] = 0; + for (i = 0; i < s->num_block_types[0]; i++) { + size_t offset = i << BROTLI_LITERAL_CONTEXT_BITS; + size_t error = 0; + size_t sample = s->context_map[offset]; + size_t j; + for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS);) { + /* NOLINTNEXTLINE(bugprone-macro-repeated-side-effects) */ + BROTLI_REPEAT_4({ error |= s->context_map[offset + j++] ^ sample; }) + } + if (error == 0) { + s->trivial_literal_contexts[i >> 5] |= 1u << (i & 31); + } + } +} + +static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) { + uint8_t context_mode; + size_t trivial; + brotli_reg_t block_type = s->block_type_rb[1]; + brotli_reg_t context_offset = block_type << BROTLI_LITERAL_CONTEXT_BITS; + s->context_map_slice = s->context_map + context_offset; + trivial = s->trivial_literal_contexts[block_type >> 5]; + s->trivial_literal_context = (trivial >> (block_type & 31)) & 1; + s->literal_htree = s->literal_hgroup.htrees[s->context_map_slice[0]]; + context_mode = s->context_modes[block_type] & 3; + s->context_lookup = BROTLI_CONTEXT_LUT(context_mode); +} + +/* Decodes the block type and updates the state for literal context. + Reads 3..54 bits. */ +static BROTLI_INLINE BROTLI_BOOL DecodeLiteralBlockSwitchInternal( + int safe, BrotliDecoderState* s) { + if (!DecodeBlockTypeAndLength(safe, s, 0)) { + return BROTLI_FALSE; + } + PrepareLiteralDecoding(s); + return BROTLI_TRUE; +} + +static void BROTLI_NOINLINE DecodeLiteralBlockSwitch(BrotliDecoderState* s) { + DecodeLiteralBlockSwitchInternal(0, s); +} + +static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeLiteralBlockSwitch( + BrotliDecoderState* s) { + return DecodeLiteralBlockSwitchInternal(1, s); +} + +/* Block switch for insert/copy length. + Reads 3..54 bits. */ +static BROTLI_INLINE BROTLI_BOOL DecodeCommandBlockSwitchInternal( + int safe, BrotliDecoderState* s) { + if (!DecodeBlockTypeAndLength(safe, s, 1)) { + return BROTLI_FALSE; + } + s->htree_command = s->insert_copy_hgroup.htrees[s->block_type_rb[3]]; + return BROTLI_TRUE; +} + +static void BROTLI_NOINLINE DecodeCommandBlockSwitch(BrotliDecoderState* s) { + DecodeCommandBlockSwitchInternal(0, s); +} + +static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeCommandBlockSwitch( + BrotliDecoderState* s) { + return DecodeCommandBlockSwitchInternal(1, s); +} + +/* Block switch for distance codes. + Reads 3..54 bits. */ +static BROTLI_INLINE BROTLI_BOOL DecodeDistanceBlockSwitchInternal( + int safe, BrotliDecoderState* s) { + if (!DecodeBlockTypeAndLength(safe, s, 2)) { + return BROTLI_FALSE; + } + s->dist_context_map_slice = s->dist_context_map + + (s->block_type_rb[5] << BROTLI_DISTANCE_CONTEXT_BITS); + s->dist_htree_index = s->dist_context_map_slice[s->distance_context]; + return BROTLI_TRUE; +} + +static void BROTLI_NOINLINE DecodeDistanceBlockSwitch(BrotliDecoderState* s) { + DecodeDistanceBlockSwitchInternal(0, s); +} + +static BROTLI_BOOL BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch( + BrotliDecoderState* s) { + return DecodeDistanceBlockSwitchInternal(1, s); +} + +static size_t UnwrittenBytes(const BrotliDecoderState* s, BROTLI_BOOL wrap) { + size_t pos = wrap && s->pos > s->ringbuffer_size ? + (size_t)s->ringbuffer_size : (size_t)(s->pos); + size_t partial_pos_rb = (s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos; + return partial_pos_rb - s->partial_pos_out; +} + +/* Dumps output. + Returns BROTLI_DECODER_NEEDS_MORE_OUTPUT only if there is more output to push + and either ring-buffer is as big as window size, or |force| is true. */ +static BrotliDecoderErrorCode BROTLI_NOINLINE WriteRingBuffer( + BrotliDecoderState* s, size_t* available_out, uint8_t** next_out, + size_t* total_out, BROTLI_BOOL force) { + uint8_t* start = + s->ringbuffer + (s->partial_pos_out & (size_t)s->ringbuffer_mask); + size_t to_write = UnwrittenBytes(s, BROTLI_TRUE); + size_t num_written = *available_out; + if (num_written > to_write) { + num_written = to_write; + } + if (s->meta_block_remaining_len < 0) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1); + } + if (next_out && !*next_out) { + *next_out = start; + } else { + if (next_out) { + memcpy(*next_out, start, num_written); + *next_out += num_written; + } + } + *available_out -= num_written; + BROTLI_LOG_UINT(to_write); + BROTLI_LOG_UINT(num_written); + s->partial_pos_out += num_written; + if (total_out) { + *total_out = s->partial_pos_out; + } + if (num_written < to_write) { + if (s->ringbuffer_size == (1 << s->window_bits) || force) { + return BROTLI_DECODER_NEEDS_MORE_OUTPUT; + } else { + return BROTLI_DECODER_SUCCESS; + } + } + /* Wrap ring buffer only if it has reached its maximal size. */ + if (s->ringbuffer_size == (1 << s->window_bits) && + s->pos >= s->ringbuffer_size) { + s->pos -= s->ringbuffer_size; + s->rb_roundtrips++; + s->should_wrap_ringbuffer = (size_t)s->pos != 0 ? 1 : 0; + } + return BROTLI_DECODER_SUCCESS; +} + +static void BROTLI_NOINLINE WrapRingBuffer(BrotliDecoderState* s) { + if (s->should_wrap_ringbuffer) { + memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos); + s->should_wrap_ringbuffer = 0; + } +} + +/* Allocates ring-buffer. + + s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before + this function is called. + + Last two bytes of ring-buffer are initialized to 0, so context calculation + could be done uniformly for the first two and all other positions. */ +static BROTLI_BOOL BROTLI_NOINLINE BrotliEnsureRingBuffer( + BrotliDecoderState* s) { + uint8_t* old_ringbuffer = s->ringbuffer; + if (s->ringbuffer_size == s->new_ringbuffer_size) { + return BROTLI_TRUE; + } + + s->ringbuffer = (uint8_t*)BROTLI_DECODER_ALLOC(s, + (size_t)(s->new_ringbuffer_size) + kRingBufferWriteAheadSlack); + if (s->ringbuffer == 0) { + /* Restore previous value. */ + s->ringbuffer = old_ringbuffer; + return BROTLI_FALSE; + } + s->ringbuffer[s->new_ringbuffer_size - 2] = 0; + s->ringbuffer[s->new_ringbuffer_size - 1] = 0; + + if (!!old_ringbuffer) { + memcpy(s->ringbuffer, old_ringbuffer, (size_t)s->pos); + BROTLI_DECODER_FREE(s, old_ringbuffer); + } + + s->ringbuffer_size = s->new_ringbuffer_size; + s->ringbuffer_mask = s->new_ringbuffer_size - 1; + s->ringbuffer_end = s->ringbuffer + s->ringbuffer_size; + + return BROTLI_TRUE; +} + +static BrotliDecoderErrorCode BROTLI_NOINLINE +SkipMetadataBlock(BrotliDecoderState* s) { + BrotliBitReader* br = &s->br; + int nbytes; + + if (s->meta_block_remaining_len == 0) { + return BROTLI_DECODER_SUCCESS; + } + + BROTLI_DCHECK((BrotliGetAvailableBits(br) & 7) == 0); + + /* Drain accumulator. */ + if (BrotliGetAvailableBits(br) >= 8) { + uint8_t buffer[8]; + nbytes = (int)(BrotliGetAvailableBits(br)) >> 3; + BROTLI_DCHECK(nbytes <= 8); + if (nbytes > s->meta_block_remaining_len) { + nbytes = s->meta_block_remaining_len; + } + BrotliCopyBytes(buffer, br, (size_t)nbytes); + if (s->metadata_chunk_func) { + s->metadata_chunk_func(s->metadata_callback_opaque, buffer, + (size_t)nbytes); + } + s->meta_block_remaining_len -= nbytes; + if (s->meta_block_remaining_len == 0) { + return BROTLI_DECODER_SUCCESS; + } + } + + /* Direct access to metadata is possible. */ + nbytes = (int)BrotliGetRemainingBytes(br); + if (nbytes > s->meta_block_remaining_len) { + nbytes = s->meta_block_remaining_len; + } + if (nbytes > 0) { + if (s->metadata_chunk_func) { + s->metadata_chunk_func(s->metadata_callback_opaque, br->next_in, + (size_t)nbytes); + } + BrotliDropBytes(br, (size_t)nbytes); + s->meta_block_remaining_len -= nbytes; + if (s->meta_block_remaining_len == 0) { + return BROTLI_DECODER_SUCCESS; + } + } + + BROTLI_DCHECK(BrotliGetRemainingBytes(br) == 0); + + return BROTLI_DECODER_NEEDS_MORE_INPUT; +} + +static BrotliDecoderErrorCode BROTLI_NOINLINE CopyUncompressedBlockToOutput( + size_t* available_out, uint8_t** next_out, size_t* total_out, + BrotliDecoderState* s) { + /* TODO(eustas): avoid allocation for single uncompressed block. */ + if (!BrotliEnsureRingBuffer(s)) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_1); + } + + /* State machine */ + for (;;) { + switch (s->substate_uncompressed) { + case BROTLI_STATE_UNCOMPRESSED_NONE: { + int nbytes = (int)BrotliGetRemainingBytes(&s->br); + if (nbytes > s->meta_block_remaining_len) { + nbytes = s->meta_block_remaining_len; + } + if (s->pos + nbytes > s->ringbuffer_size) { + nbytes = s->ringbuffer_size - s->pos; + } + /* Copy remaining bytes from s->br.buf_ to ring-buffer. */ + BrotliCopyBytes(&s->ringbuffer[s->pos], &s->br, (size_t)nbytes); + s->pos += nbytes; + s->meta_block_remaining_len -= nbytes; + if (s->pos < 1 << s->window_bits) { + if (s->meta_block_remaining_len == 0) { + return BROTLI_DECODER_SUCCESS; + } + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_WRITE; + } + /* Fall through. */ + + case BROTLI_STATE_UNCOMPRESSED_WRITE: { + BrotliDecoderErrorCode result; + result = WriteRingBuffer( + s, available_out, next_out, total_out, BROTLI_FALSE); + if (result != BROTLI_DECODER_SUCCESS) { + return result; + } + if (s->ringbuffer_size == 1 << s->window_bits) { + s->max_distance = s->max_backward_distance; + } + s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE; + break; + } + } + } + BROTLI_DCHECK(0); /* Unreachable */ +} + +static BROTLI_BOOL AttachCompoundDictionary( + BrotliDecoderState* state, const uint8_t* data, size_t size) { + BrotliDecoderCompoundDictionary* addon = state->compound_dictionary; + if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE; + if (!addon) { + addon = (BrotliDecoderCompoundDictionary*)BROTLI_DECODER_ALLOC( + state, sizeof(BrotliDecoderCompoundDictionary)); + if (!addon) return BROTLI_FALSE; + addon->num_chunks = 0; + addon->total_size = 0; + addon->br_length = 0; + addon->br_copied = 0; + addon->block_bits = -1; + addon->chunk_offsets[0] = 0; + state->compound_dictionary = addon; + } + if (addon->num_chunks == 15) return BROTLI_FALSE; + addon->chunks[addon->num_chunks] = data; + addon->num_chunks++; + addon->total_size += (int)size; + addon->chunk_offsets[addon->num_chunks] = addon->total_size; + return BROTLI_TRUE; +} + +static void EnsureCompoundDictionaryInitialized(BrotliDecoderState* state) { + BrotliDecoderCompoundDictionary* addon = state->compound_dictionary; + /* 256 = (1 << 8) slots in block map. */ + int block_bits = 8; + int cursor = 0; + int index = 0; + if (addon->block_bits != -1) return; + while (((addon->total_size - 1) >> block_bits) != 0) block_bits++; + block_bits -= 8; + addon->block_bits = block_bits; + while (cursor < addon->total_size) { + while (addon->chunk_offsets[index + 1] < cursor) index++; + addon->block_map[cursor >> block_bits] = (uint8_t)index; + cursor += 1 << block_bits; + } +} + +static BROTLI_BOOL InitializeCompoundDictionaryCopy(BrotliDecoderState* s, + int address, int length) { + BrotliDecoderCompoundDictionary* addon = s->compound_dictionary; + int index; + EnsureCompoundDictionaryInitialized(s); + index = addon->block_map[address >> addon->block_bits]; + while (address >= addon->chunk_offsets[index + 1]) index++; + if (addon->total_size < address + length) return BROTLI_FALSE; + /* Update the recent distances cache. */ + s->dist_rb[s->dist_rb_idx & 3] = s->distance_code; + ++s->dist_rb_idx; + s->meta_block_remaining_len -= length; + addon->br_index = index; + addon->br_offset = address - addon->chunk_offsets[index]; + addon->br_length = length; + addon->br_copied = 0; + return BROTLI_TRUE; +} + +static int GetCompoundDictionarySize(BrotliDecoderState* s) { + return s->compound_dictionary ? s->compound_dictionary->total_size : 0; +} + +static int CopyFromCompoundDictionary(BrotliDecoderState* s, int pos) { + BrotliDecoderCompoundDictionary* addon = s->compound_dictionary; + int orig_pos = pos; + while (addon->br_length != addon->br_copied) { + uint8_t* copy_dst = &s->ringbuffer[pos]; + const uint8_t* copy_src = + addon->chunks[addon->br_index] + addon->br_offset; + int space = s->ringbuffer_size - pos; + int rem_chunk_length = (addon->chunk_offsets[addon->br_index + 1] - + addon->chunk_offsets[addon->br_index]) - addon->br_offset; + int length = addon->br_length - addon->br_copied; + if (length > rem_chunk_length) length = rem_chunk_length; + if (length > space) length = space; + memcpy(copy_dst, copy_src, (size_t)length); + pos += length; + addon->br_offset += length; + addon->br_copied += length; + if (length == rem_chunk_length) { + addon->br_index++; + addon->br_offset = 0; + } + if (pos == s->ringbuffer_size) break; + } + return pos - orig_pos; +} + +BROTLI_BOOL BrotliDecoderAttachDictionary( + BrotliDecoderState* state, BrotliSharedDictionaryType type, + size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]) { + brotli_reg_t i; + brotli_reg_t num_prefix_before = state->dictionary->num_prefix; + if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE; + if (!BrotliSharedDictionaryAttach(state->dictionary, type, data_size, data)) { + return BROTLI_FALSE; + } + for (i = num_prefix_before; i < state->dictionary->num_prefix; i++) { + if (!AttachCompoundDictionary( + state, state->dictionary->prefix[i], + state->dictionary->prefix_size[i])) { + return BROTLI_FALSE; + } + } + return BROTLI_TRUE; +} + +/* Calculates the smallest feasible ring buffer. + + If we know the data size is small, do not allocate more ring buffer + size than needed to reduce memory usage. + + When this method is called, metablock size and flags MUST be decoded. */ +static void BROTLI_NOINLINE BrotliCalculateRingBufferSize( + BrotliDecoderState* s) { + int window_size = 1 << s->window_bits; + int new_ringbuffer_size = window_size; + /* We need at least 2 bytes of ring buffer size to get the last two + bytes for context from there */ + int min_size = s->ringbuffer_size ? s->ringbuffer_size : 1024; + int output_size; + + /* If maximum is already reached, no further extension is retired. */ + if (s->ringbuffer_size == window_size) { + return; + } + + /* Metadata blocks does not touch ring buffer. */ + if (s->is_metadata) { + return; + } + + if (!s->ringbuffer) { + output_size = 0; + } else { + output_size = s->pos; + } + output_size += s->meta_block_remaining_len; + min_size = min_size < output_size ? output_size : min_size; + + if (!!s->canny_ringbuffer_allocation) { + /* Reduce ring buffer size to save memory when server is unscrupulous. + In worst case memory usage might be 1.5x bigger for a short period of + ring buffer reallocation. */ + while ((new_ringbuffer_size >> 1) >= min_size) { + new_ringbuffer_size >>= 1; + } + } + + s->new_ringbuffer_size = new_ringbuffer_size; +} + +/* Reads 1..256 2-bit context modes. */ +static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) { + BrotliBitReader* br = &s->br; + int i = s->loop_counter; + + while (i < (int)s->num_block_types[0]) { + brotli_reg_t bits; + if (!BrotliSafeReadBits(br, 2, &bits)) { + s->loop_counter = i; + return BROTLI_DECODER_NEEDS_MORE_INPUT; + } + s->context_modes[i] = (uint8_t)bits; + BROTLI_LOG_ARRAY_INDEX(s->context_modes, i); + i++; + } + return BROTLI_DECODER_SUCCESS; +} + +static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) { + int offset = s->distance_code - 3; + if (s->distance_code <= 3) { + /* Compensate double distance-ring-buffer roll for dictionary items. */ + s->distance_context = 1 >> s->distance_code; + s->distance_code = s->dist_rb[(s->dist_rb_idx - offset) & 3]; + s->dist_rb_idx -= s->distance_context; + } else { + int index_delta = 3; + int delta; + int base = s->distance_code - 10; + if (s->distance_code < 10) { + base = s->distance_code - 4; + } else { + index_delta = 2; + } + /* Unpack one of six 4-bit values. */ + delta = ((0x605142 >> (4 * base)) & 0xF) - 3; + s->distance_code = s->dist_rb[(s->dist_rb_idx + index_delta) & 0x3] + delta; + if (s->distance_code <= 0) { + /* A huge distance will cause a BROTLI_FAILURE() soon. + This is a little faster than failing here. */ + s->distance_code = 0x7FFFFFFF; + } + } +} + +static BROTLI_INLINE BROTLI_BOOL SafeReadBits( + BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) { + if (n_bits != 0) { + return BrotliSafeReadBits(br, n_bits, val); + } else { + *val = 0; + return BROTLI_TRUE; + } +} + +static BROTLI_INLINE BROTLI_BOOL SafeReadBits32( + BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) { + if (n_bits != 0) { + return BrotliSafeReadBits32(br, n_bits, val); + } else { + *val = 0; + return BROTLI_TRUE; + } +} + +/* + RFC 7932 Section 4 with "..." shortenings and "[]" emendations. + + Each distance ... is represented with a pair ... + The distance code is encoded using a prefix code... The number of extra bits + can be 0..24... Two additional parameters: NPOSTFIX (0..3), and ... + NDIRECT (0..120) ... are encoded in the meta-block header... + + The first 16 distance symbols ... reference past distances... ring buffer ... + Next NDIRECT distance symbols ... represent distances from 1 to NDIRECT... + [For] distance symbols 16 + NDIRECT and greater ... the number of extra bits + ... is given by the following formula: + + [ xcode = dcode - NDIRECT - 16 ] + ndistbits = 1 + [ xcode ] >> (NPOSTFIX + 1) + + ... +*/ + +/* + RFC 7932 Section 9.2 with "..." shortenings and "[]" emendations. + + ... to get the actual value of the parameter NDIRECT, left-shift this + four-bit number by NPOSTFIX bits ... +*/ + +/* Remaining formulas from RFC 7932 Section 4 could be rewritten as following: + + alphabet_size = 16 + NDIRECT + (max_distbits << (NPOSTFIX + 1)) + + half = ((xcode >> NPOSTFIX) & 1) << ndistbits + postfix = xcode & ((1 << NPOSTFIX) - 1) + range_start = 2 * (1 << ndistbits - 1 - 1) + + distance = (range_start + half + extra) << NPOSTFIX + postfix + NDIRECT + 1 + + NB: ndistbits >= 1 -> range_start >= 0 + NB: range_start has factor 2, as the range is covered by 2 "halves" + NB: extra -1 offset in range_start formula covers the absence of + ndistbits = 0 case + NB: when NPOSTFIX = 0, NDIRECT is not greater than 15 + + In other words, xcode has the following binary structure - XXXHPPP: + - XXX represent the number of extra distance bits + - H selects upper / lower range of distances + - PPP represent "postfix" + + "Regular" distance encoding has NPOSTFIX = 0; omitting the postfix part + simplifies distance calculation. + + Using NPOSTFIX > 0 allows cheaper encoding of regular structures, e.g. where + most of distances have the same reminder of division by 2/4/8. For example, + the table of int32_t values that come from different sources; if it is likely + that 3 highest bytes of values from the same source are the same, then + copy distance often looks like 4x + y. + + Distance calculation could be rewritten to: + + ndistbits = NDISTBITS(NDIRECT, NPOSTFIX)[dcode] + distance = OFFSET(NDIRECT, NPOSTFIX)[dcode] + extra << NPOSTFIX + + NDISTBITS and OFFSET could be pre-calculated, as NDIRECT and NPOSTFIX could + change only once per meta-block. +*/ + +/* Calculates distance lookup table. + NB: it is possible to have all 64 tables precalculated. */ +static void CalculateDistanceLut(BrotliDecoderState* s) { + BrotliMetablockBodyArena* b = &s->arena.body; + brotli_reg_t npostfix = s->distance_postfix_bits; + brotli_reg_t ndirect = s->num_direct_distance_codes; + brotli_reg_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit; + brotli_reg_t postfix = (brotli_reg_t)1u << npostfix; + brotli_reg_t j; + brotli_reg_t bits = 1; + brotli_reg_t half = 0; + + /* Skip short codes. */ + brotli_reg_t i = BROTLI_NUM_DISTANCE_SHORT_CODES; + + /* Fill direct codes. */ + for (j = 0; j < ndirect; ++j) { + b->dist_extra_bits[i] = 0; + b->dist_offset[i] = j + 1; + ++i; + } + + /* Fill regular distance codes. */ + while (i < alphabet_size_limit) { + brotli_reg_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1; + /* Always fill the complete group. */ + for (j = 0; j < postfix; ++j) { + b->dist_extra_bits[i] = (uint8_t)bits; + b->dist_offset[i] = base + j; + ++i; + } + bits = bits + half; + half = half ^ 1; + } +} + +/* Precondition: s->distance_code < 0. */ +static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal( + int safe, BrotliDecoderState* s, BrotliBitReader* br) { + BrotliMetablockBodyArena* b = &s->arena.body; + brotli_reg_t code; + brotli_reg_t bits; + BrotliBitReaderState memento; + HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index]; + if (!safe) { + code = ReadSymbol(distance_tree, br); + } else { + BrotliBitReaderSaveState(br, &memento); + if (!SafeReadSymbol(distance_tree, br, &code)) { + return BROTLI_FALSE; + } + } + --s->block_length[2]; + /* Convert the distance code to the actual distance by possibly + looking up past distances from the s->dist_rb. */ + s->distance_context = 0; + if ((code & ~0xFu) == 0) { + s->distance_code = (int)code; + TakeDistanceFromRingBuffer(s); + return BROTLI_TRUE; + } + if (!safe) { + bits = BrotliReadBits32(br, b->dist_extra_bits[code]); + } else { + if (!SafeReadBits32(br, b->dist_extra_bits[code], &bits)) { + ++s->block_length[2]; + BrotliBitReaderRestoreState(br, &memento); + return BROTLI_FALSE; + } + } + s->distance_code = + (int)(b->dist_offset[code] + (bits << s->distance_postfix_bits)); + return BROTLI_TRUE; +} + +static BROTLI_INLINE void ReadDistance( + BrotliDecoderState* s, BrotliBitReader* br) { + ReadDistanceInternal(0, s, br); +} + +static BROTLI_INLINE BROTLI_BOOL SafeReadDistance( + BrotliDecoderState* s, BrotliBitReader* br) { + return ReadDistanceInternal(1, s, br); +} + +static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal( + int safe, BrotliDecoderState* s, BrotliBitReader* br, int* insert_length) { + brotli_reg_t cmd_code; + brotli_reg_t insert_len_extra = 0; + brotli_reg_t copy_length; + CmdLutElement v; + BrotliBitReaderState memento; + if (!safe) { + cmd_code = ReadSymbol(s->htree_command, br); + } else { + BrotliBitReaderSaveState(br, &memento); + if (!SafeReadSymbol(s->htree_command, br, &cmd_code)) { + return BROTLI_FALSE; + } + } + v = kCmdLut[cmd_code]; + s->distance_code = v.distance_code; + s->distance_context = v.context; + s->dist_htree_index = s->dist_context_map_slice[s->distance_context]; + *insert_length = v.insert_len_offset; + if (!safe) { + if (BROTLI_PREDICT_FALSE(v.insert_len_extra_bits != 0)) { + insert_len_extra = BrotliReadBits24(br, v.insert_len_extra_bits); + } + copy_length = BrotliReadBits24(br, v.copy_len_extra_bits); + } else { + if (!SafeReadBits(br, v.insert_len_extra_bits, &insert_len_extra) || + !SafeReadBits(br, v.copy_len_extra_bits, ©_length)) { + BrotliBitReaderRestoreState(br, &memento); + return BROTLI_FALSE; + } + } + s->copy_length = (int)copy_length + v.copy_len_offset; + --s->block_length[1]; + *insert_length += (int)insert_len_extra; + return BROTLI_TRUE; +} + +static BROTLI_INLINE void ReadCommand( + BrotliDecoderState* s, BrotliBitReader* br, int* insert_length) { + ReadCommandInternal(0, s, br, insert_length); +} + +static BROTLI_INLINE BROTLI_BOOL SafeReadCommand( + BrotliDecoderState* s, BrotliBitReader* br, int* insert_length) { + return ReadCommandInternal(1, s, br, insert_length); +} + +static BROTLI_INLINE BROTLI_BOOL CheckInputAmount( + int safe, BrotliBitReader* const br) { + if (safe) { + return BROTLI_TRUE; + } + return BrotliCheckInputAmount(br); +} + +#define BROTLI_SAFE(METHOD) \ + { \ + if (safe) { \ + if (!Safe##METHOD) { \ + result = BROTLI_DECODER_NEEDS_MORE_INPUT; \ + goto saveStateAndReturn; \ + } \ + } else { \ + METHOD; \ + } \ + } + +static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal( + int safe, BrotliDecoderState* s) { + int pos = s->pos; + int i = s->loop_counter; + BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS; + BrotliBitReader* br = &s->br; + int compound_dictionary_size = GetCompoundDictionarySize(s); + + if (!CheckInputAmount(safe, br)) { + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + if (!safe) { + BROTLI_UNUSED(BrotliWarmupBitReader(br)); + } + + /* Jump into state machine. */ + if (s->state == BROTLI_STATE_COMMAND_BEGIN) { + goto CommandBegin; + } else if (s->state == BROTLI_STATE_COMMAND_INNER) { + goto CommandInner; + } else if (s->state == BROTLI_STATE_COMMAND_POST_DECODE_LITERALS) { + goto CommandPostDecodeLiterals; + } else if (s->state == BROTLI_STATE_COMMAND_POST_WRAP_COPY) { + goto CommandPostWrapCopy; + } else { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_UNREACHABLE); /* COV_NF_LINE */ + } + +CommandBegin: + if (safe) { + s->state = BROTLI_STATE_COMMAND_BEGIN; + } + if (!CheckInputAmount(safe, br)) { + s->state = BROTLI_STATE_COMMAND_BEGIN; + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + if (BROTLI_PREDICT_FALSE(s->block_length[1] == 0)) { + BROTLI_SAFE(DecodeCommandBlockSwitch(s)); + goto CommandBegin; + } + /* Read the insert/copy length in the command. */ + BROTLI_SAFE(ReadCommand(s, br, &i)); + BROTLI_LOG(("[ProcessCommandsInternal] pos = %d insert = %d copy = %d\n", + pos, i, s->copy_length)); + if (i == 0) { + goto CommandPostDecodeLiterals; + } + s->meta_block_remaining_len -= i; + +CommandInner: + if (safe) { + s->state = BROTLI_STATE_COMMAND_INNER; + } + /* Read the literals in the command. */ + if (s->trivial_literal_context) { + brotli_reg_t bits; + brotli_reg_t value; + PreloadSymbol(safe, s->literal_htree, br, &bits, &value); + if (!safe) { + // This is a hottest part of the decode, so we copy the loop below + // and optimize it by calculating the number of steps where all checks + // evaluate to false (ringbuffer size/block size/input size). + // Since all checks are loop invariant, we just need to find + // minimal number of iterations for a simple loop, and run + // the full version for the remainder. + int num_steps = i - 1; + if (num_steps > 0 && ((brotli_reg_t)(num_steps) > s->block_length[0])) { + // Safe cast, since block_length < steps + num_steps = (int)s->block_length[0]; + } + if (s->ringbuffer_size >= pos && + (s->ringbuffer_size - pos) <= num_steps) { + num_steps = s->ringbuffer_size - pos - 1; + } + if (num_steps < 0) { + num_steps = 0; + } + num_steps = BrotliCopyPreloadedSymbolsToU8(s->literal_htree, br, &bits, + &value, s->ringbuffer, pos, + num_steps); + pos += num_steps; + s->block_length[0] -= (brotli_reg_t)num_steps; + i -= num_steps; + do { + if (!CheckInputAmount(safe, br)) { + s->state = BROTLI_STATE_COMMAND_INNER; + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) { + goto NextLiteralBlock; + } + BrotliCopyPreloadedSymbolsToU8(s->literal_htree, br, &bits, &value, + s->ringbuffer, pos, 1); + --s->block_length[0]; + BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos); + ++pos; + if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) { + s->state = BROTLI_STATE_COMMAND_INNER_WRITE; + --i; + goto saveStateAndReturn; + } + } while (--i != 0); + } else { /* safe */ + do { + if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) { + goto NextLiteralBlock; + } + brotli_reg_t literal; + if (!SafeReadSymbol(s->literal_htree, br, &literal)) { + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + s->ringbuffer[pos] = (uint8_t)literal; + --s->block_length[0]; + BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos); + ++pos; + if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) { + s->state = BROTLI_STATE_COMMAND_INNER_WRITE; + --i; + goto saveStateAndReturn; + } + } while (--i != 0); + } + } else { + uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask]; + uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask]; + do { + const HuffmanCode* hc; + uint8_t context; + if (!CheckInputAmount(safe, br)) { + s->state = BROTLI_STATE_COMMAND_INNER; + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) { + goto NextLiteralBlock; + } + context = BROTLI_CONTEXT(p1, p2, s->context_lookup); + BROTLI_LOG_UINT(context); + hc = s->literal_hgroup.htrees[s->context_map_slice[context]]; + p2 = p1; + if (!safe) { + p1 = (uint8_t)ReadSymbol(hc, br); + } else { + brotli_reg_t literal; + if (!SafeReadSymbol(hc, br, &literal)) { + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + goto saveStateAndReturn; + } + p1 = (uint8_t)literal; + } + s->ringbuffer[pos] = p1; + --s->block_length[0]; + BROTLI_LOG_UINT(s->context_map_slice[context]); + BROTLI_LOG_ARRAY_INDEX(s->ringbuffer, pos & s->ringbuffer_mask); + ++pos; + if (BROTLI_PREDICT_FALSE(pos == s->ringbuffer_size)) { + s->state = BROTLI_STATE_COMMAND_INNER_WRITE; + --i; + goto saveStateAndReturn; + } + } while (--i != 0); + } + BROTLI_LOG_UINT(s->meta_block_remaining_len); + if (BROTLI_PREDICT_FALSE(s->meta_block_remaining_len <= 0)) { + s->state = BROTLI_STATE_METABLOCK_DONE; + goto saveStateAndReturn; + } + +CommandPostDecodeLiterals: + if (safe) { + s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS; + } + if (s->distance_code >= 0) { + /* Implicit distance case. */ + s->distance_context = s->distance_code ? 0 : 1; + --s->dist_rb_idx; + s->distance_code = s->dist_rb[s->dist_rb_idx & 3]; + } else { + /* Read distance code in the command, unless it was implicitly zero. */ + if (BROTLI_PREDICT_FALSE(s->block_length[2] == 0)) { + BROTLI_SAFE(DecodeDistanceBlockSwitch(s)); + } + BROTLI_SAFE(ReadDistance(s, br)); + } + BROTLI_LOG(("[ProcessCommandsInternal] pos = %d distance = %d\n", + pos, s->distance_code)); + if (s->max_distance != s->max_backward_distance) { + s->max_distance = + (pos < s->max_backward_distance) ? pos : s->max_backward_distance; + } + i = s->copy_length; + /* Apply copy of LZ77 back-reference, or static dictionary reference if + the distance is larger than the max LZ77 distance */ + if (s->distance_code > s->max_distance) { + /* The maximum allowed distance is BROTLI_MAX_ALLOWED_DISTANCE = 0x7FFFFFFC. + With this choice, no signed overflow can occur after decoding + a special distance code (e.g., after adding 3 to the last distance). */ + if (s->distance_code > BROTLI_MAX_ALLOWED_DISTANCE) { + BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", + pos, s->distance_code, i, s->meta_block_remaining_len)); + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_DISTANCE); + } + if (s->distance_code - s->max_distance - 1 < compound_dictionary_size) { + int address = compound_dictionary_size - + (s->distance_code - s->max_distance); + if (!InitializeCompoundDictionaryCopy(s, address, i)) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_COMPOUND_DICTIONARY); + } + pos += CopyFromCompoundDictionary(s, pos); + if (pos >= s->ringbuffer_size) { + s->state = BROTLI_STATE_COMMAND_POST_WRITE_1; + goto saveStateAndReturn; + } + } else if (i >= SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH && + i <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH) { + uint8_t p1 = s->ringbuffer[(pos - 1) & s->ringbuffer_mask]; + uint8_t p2 = s->ringbuffer[(pos - 2) & s->ringbuffer_mask]; + uint8_t dict_id = s->dictionary->context_based ? + s->dictionary->context_map[BROTLI_CONTEXT(p1, p2, s->context_lookup)] + : 0; + const BrotliDictionary* words = s->dictionary->words[dict_id]; + const BrotliTransforms* transforms = s->dictionary->transforms[dict_id]; + int offset = (int)words->offsets_by_length[i]; + brotli_reg_t shift = words->size_bits_by_length[i]; + int address = + s->distance_code - s->max_distance - 1 - compound_dictionary_size; + int mask = (int)BitMask(shift); + int word_idx = address & mask; + int transform_idx = address >> shift; + /* Compensate double distance-ring-buffer roll. */ + s->dist_rb_idx += s->distance_context; + offset += word_idx * i; + /* If the distance is out of bound, select a next static dictionary if + there exist multiple. */ + if ((transform_idx >= (int)transforms->num_transforms || + words->size_bits_by_length[i] == 0) && + s->dictionary->num_dictionaries > 1) { + uint8_t dict_id2; + int dist_remaining = address - + (int)(((1u << shift) & ~1u)) * (int)transforms->num_transforms; + for (dict_id2 = 0; dict_id2 < s->dictionary->num_dictionaries; + dict_id2++) { + const BrotliDictionary* words2 = s->dictionary->words[dict_id2]; + if (dict_id2 != dict_id && words2->size_bits_by_length[i] != 0) { + const BrotliTransforms* transforms2 = + s->dictionary->transforms[dict_id2]; + brotli_reg_t shift2 = words2->size_bits_by_length[i]; + int num = (int)((1u << shift2) & ~1u) * + (int)transforms2->num_transforms; + if (dist_remaining < num) { + dict_id = dict_id2; + words = words2; + transforms = transforms2; + address = dist_remaining; + shift = shift2; + mask = (int)BitMask(shift); + word_idx = address & mask; + transform_idx = address >> shift; + offset = (int)words->offsets_by_length[i] + word_idx * i; + break; + } + dist_remaining -= num; + } + } + } + if (BROTLI_PREDICT_FALSE(words->size_bits_by_length[i] == 0)) { + BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", + pos, s->distance_code, i, s->meta_block_remaining_len)); + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_DICTIONARY); + } + if (BROTLI_PREDICT_FALSE(!words->data)) { + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_DICTIONARY_NOT_SET); + } + if (transform_idx < (int)transforms->num_transforms) { + const uint8_t* word = &words->data[offset]; + int len = i; + if (transform_idx == transforms->cutOffTransforms[0]) { + memcpy(&s->ringbuffer[pos], word, (size_t)len); + BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s]\n", + len, word)); + } else { + len = BrotliTransformDictionaryWord(&s->ringbuffer[pos], word, len, + transforms, transform_idx); + BROTLI_LOG(("[ProcessCommandsInternal] dictionary word: [%.*s]," + " transform_idx = %d, transformed: [%.*s]\n", + i, word, transform_idx, len, &s->ringbuffer[pos])); + if (len == 0 && s->distance_code <= 120) { + BROTLI_LOG(("Invalid length-0 dictionary word after transform\n")); + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_TRANSFORM); + } + } + pos += len; + s->meta_block_remaining_len -= len; + if (pos >= s->ringbuffer_size) { + s->state = BROTLI_STATE_COMMAND_POST_WRITE_1; + goto saveStateAndReturn; + } + } else { + BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", + pos, s->distance_code, i, s->meta_block_remaining_len)); + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_TRANSFORM); + } + } else { + BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d " + "len: %d bytes left: %d\n", + pos, s->distance_code, i, s->meta_block_remaining_len)); + return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_DICTIONARY); + } + } else { + int src_start = (pos - s->distance_code) & s->ringbuffer_mask; + uint8_t* copy_dst = &s->ringbuffer[pos]; + uint8_t* copy_src = &s->ringbuffer[src_start]; + int dst_end = pos + i; + int src_end = src_start + i; + /* Update the recent distances cache. */ + s->dist_rb[s->dist_rb_idx & 3] = s->distance_code; + ++s->dist_rb_idx; + s->meta_block_remaining_len -= i; + /* There are 32+ bytes of slack in the ring-buffer allocation. + Also, we have 16 short codes, that make these 16 bytes irrelevant + in the ring-buffer. Let's copy over them as a first guess. */ + memmove16(copy_dst, copy_src); + if (src_end > pos && dst_end > src_start) { + /* Regions intersect. */ + goto CommandPostWrapCopy; + } + if (dst_end >= s->ringbuffer_size || src_end >= s->ringbuffer_size) { + /* At least one region wraps. */ + goto CommandPostWrapCopy; + } + pos += i; + if (i > 16) { + if (i > 32) { + memcpy(copy_dst + 16, copy_src + 16, (size_t)(i - 16)); + } else { + /* This branch covers about 45% cases. + Fixed size short copy allows more compiler optimizations. */ + memmove16(copy_dst + 16, copy_src + 16); + } + } + } + BROTLI_LOG_UINT(s->meta_block_remaining_len); + if (s->meta_block_remaining_len <= 0) { + /* Next metablock, if any. */ + s->state = BROTLI_STATE_METABLOCK_DONE; + goto saveStateAndReturn; + } else { + goto CommandBegin; + } +CommandPostWrapCopy: + { + int wrap_guard = s->ringbuffer_size - pos; + while (--i >= 0) { + s->ringbuffer[pos] = + s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask]; + ++pos; + if (BROTLI_PREDICT_FALSE(--wrap_guard == 0)) { + s->state = BROTLI_STATE_COMMAND_POST_WRITE_2; + goto saveStateAndReturn; + } + } + } + if (s->meta_block_remaining_len <= 0) { + /* Next metablock, if any. */ + s->state = BROTLI_STATE_METABLOCK_DONE; + goto saveStateAndReturn; + } else { + goto CommandBegin; + } + +NextLiteralBlock: + BROTLI_SAFE(DecodeLiteralBlockSwitch(s)); + goto CommandInner; + +saveStateAndReturn: + s->pos = pos; + s->loop_counter = i; + return result; +} + +#undef BROTLI_SAFE + +static BROTLI_NOINLINE BrotliDecoderErrorCode ProcessCommands( + BrotliDecoderState* s) { + return ProcessCommandsInternal(0, s); +} + +static BROTLI_NOINLINE BrotliDecoderErrorCode SafeProcessCommands( + BrotliDecoderState* s) { + return ProcessCommandsInternal(1, s); +} + +BrotliDecoderResult BrotliDecoderDecompress( + size_t encoded_size, + const uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(encoded_size)], + size_t* decoded_size, + uint8_t decoded_buffer[BROTLI_ARRAY_PARAM(*decoded_size)]) { + BrotliDecoderState s; + BrotliDecoderResult result; + size_t total_out = 0; + size_t available_in = encoded_size; + const uint8_t* next_in = encoded_buffer; + size_t available_out = *decoded_size; + uint8_t* next_out = decoded_buffer; + if (!BrotliDecoderStateInit(&s, 0, 0, 0)) { + return BROTLI_DECODER_RESULT_ERROR; + } + result = BrotliDecoderDecompressStream( + &s, &available_in, &next_in, &available_out, &next_out, &total_out); + *decoded_size = total_out; + BrotliDecoderStateCleanup(&s); + if (result != BROTLI_DECODER_RESULT_SUCCESS) { + result = BROTLI_DECODER_RESULT_ERROR; + } + return result; +} + +/* Invariant: input stream is never overconsumed: + - invalid input implies that the whole stream is invalid -> any amount of + input could be read and discarded + - when result is "needs more input", then at least one more byte is REQUIRED + to complete decoding; all input data MUST be consumed by decoder, so + client could swap the input buffer + - when result is "needs more output" decoder MUST ensure that it doesn't + hold more than 7 bits in bit reader; this saves client from swapping input + buffer ahead of time + - when result is "success" decoder MUST return all unused data back to input + buffer; this is possible because the invariant is held on enter */ +BrotliDecoderResult BrotliDecoderDecompressStream( + BrotliDecoderState* s, size_t* available_in, const uint8_t** next_in, + size_t* available_out, uint8_t** next_out, size_t* total_out) { + BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS; + BrotliBitReader* br = &s->br; + size_t input_size = *available_in; +#define BROTLI_SAVE_ERROR_CODE(code) \ + SaveErrorCode(s, (code), input_size - *available_in) + /* Ensure that |total_out| is set, even if no data will ever be pushed out. */ + if (total_out) { + *total_out = s->partial_pos_out; + } + /* Do not try to process further in a case of unrecoverable error. */ + if ((int)s->error_code < 0) { + return BROTLI_DECODER_RESULT_ERROR; + } + if (*available_out && (!next_out || !*next_out)) { + return BROTLI_SAVE_ERROR_CODE( + BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS)); + } + if (!*available_out) next_out = 0; + if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */ + BrotliBitReaderSetInput(br, *next_in, *available_in); + } else { + /* At least one byte of input is required. More than one byte of input may + be required to complete the transaction -> reading more data must be + done in a loop -> do it in a main loop. */ + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + BrotliBitReaderSetInput(br, &s->buffer.u8[0], s->buffer_length); + } + /* State machine */ + for (;;) { + if (result != BROTLI_DECODER_SUCCESS) { + /* Error, needs more input/output. */ + if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) { + if (s->ringbuffer != 0) { /* Pro-actively push output. */ + BrotliDecoderErrorCode intermediate_result = WriteRingBuffer(s, + available_out, next_out, total_out, BROTLI_TRUE); + /* WriteRingBuffer checks s->meta_block_remaining_len validity. */ + if ((int)intermediate_result < 0) { + result = intermediate_result; + break; + } + } + if (s->buffer_length != 0) { /* Used with internal buffer. */ + if (br->next_in == br->last_in) { + /* Successfully finished read transaction. + Accumulator contains less than 8 bits, because internal buffer + is expanded byte-by-byte until it is enough to complete read. */ + s->buffer_length = 0; + /* Switch to input stream and restart. */ + result = BROTLI_DECODER_SUCCESS; + BrotliBitReaderSetInput(br, *next_in, *available_in); + continue; + } else if (*available_in != 0) { + /* Not enough data in buffer, but can take one more byte from + input stream. */ + result = BROTLI_DECODER_SUCCESS; + BROTLI_DCHECK(s->buffer_length < 8); + s->buffer.u8[s->buffer_length] = **next_in; + s->buffer_length++; + BrotliBitReaderSetInput(br, &s->buffer.u8[0], s->buffer_length); + (*next_in)++; + (*available_in)--; + /* Retry with more data in buffer. */ + continue; + } + /* Can't finish reading and no more input. */ + break; + } else { /* Input stream doesn't contain enough input. */ + /* Copy tail to internal buffer and return. */ + *next_in = br->next_in; + *available_in = BrotliBitReaderGetAvailIn(br); + while (*available_in) { + s->buffer.u8[s->buffer_length] = **next_in; + s->buffer_length++; + (*next_in)++; + (*available_in)--; + } + break; + } + /* Unreachable. */ + } + + /* Fail or needs more output. */ + + if (s->buffer_length != 0) { + /* Just consumed the buffered input and produced some output. Otherwise + it would result in "needs more input". Reset internal buffer. */ + s->buffer_length = 0; + } else { + /* Using input stream in last iteration. When decoder switches to input + stream it has less than 8 bits in accumulator, so it is safe to + return unused accumulator bits there. */ + BrotliBitReaderUnload(br); + *available_in = BrotliBitReaderGetAvailIn(br); + *next_in = br->next_in; + } + break; + } + switch (s->state) { + case BROTLI_STATE_UNINITED: + /* Prepare to the first read. */ + if (!BrotliWarmupBitReader(br)) { + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + break; + } + /* Decode window size. */ + result = DecodeWindowBits(s, br); /* Reads 1..8 bits. */ + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + if (s->large_window) { + s->state = BROTLI_STATE_LARGE_WINDOW_BITS; + break; + } + s->state = BROTLI_STATE_INITIALIZE; + break; + + case BROTLI_STATE_LARGE_WINDOW_BITS: { + brotli_reg_t bits; + if (!BrotliSafeReadBits(br, 6, &bits)) { + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + break; + } + s->window_bits = bits & 63u; + if (s->window_bits < BROTLI_LARGE_MIN_WBITS || + s->window_bits > BROTLI_LARGE_MAX_WBITS) { + result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS); + break; + } + s->state = BROTLI_STATE_INITIALIZE; + } + /* Fall through. */ + + case BROTLI_STATE_INITIALIZE: + BROTLI_LOG_UINT(s->window_bits); + /* Maximum distance, see section 9.1. of the spec. */ + s->max_backward_distance = (1 << s->window_bits) - BROTLI_WINDOW_GAP; + + /* Allocate memory for both block_type_trees and block_len_trees. */ + s->block_type_trees = (HuffmanCode*)BROTLI_DECODER_ALLOC(s, + sizeof(HuffmanCode) * 3 * + (BROTLI_HUFFMAN_MAX_SIZE_258 + BROTLI_HUFFMAN_MAX_SIZE_26)); + if (s->block_type_trees == 0) { + result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_BLOCK_TYPE_TREES); + break; + } + s->block_len_trees = + s->block_type_trees + 3 * BROTLI_HUFFMAN_MAX_SIZE_258; + + s->state = BROTLI_STATE_METABLOCK_BEGIN; + /* Fall through. */ + + case BROTLI_STATE_METABLOCK_BEGIN: + BrotliDecoderStateMetablockBegin(s); + BROTLI_LOG_UINT(s->pos); + s->state = BROTLI_STATE_METABLOCK_HEADER; + /* Fall through. */ + + case BROTLI_STATE_METABLOCK_HEADER: + result = DecodeMetaBlockLength(s, br); /* Reads 2 - 31 bits. */ + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + BROTLI_LOG_UINT(s->is_last_metablock); + BROTLI_LOG_UINT(s->meta_block_remaining_len); + BROTLI_LOG_UINT(s->is_metadata); + BROTLI_LOG_UINT(s->is_uncompressed); + if (s->is_metadata || s->is_uncompressed) { + if (!BrotliJumpToByteBoundary(br)) { + result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_PADDING_1); + break; + } + } + if (s->is_metadata) { + s->state = BROTLI_STATE_METADATA; + if (s->metadata_start_func) { + s->metadata_start_func(s->metadata_callback_opaque, + (size_t)s->meta_block_remaining_len); + } + break; + } + if (s->meta_block_remaining_len == 0) { + s->state = BROTLI_STATE_METABLOCK_DONE; + break; + } + BrotliCalculateRingBufferSize(s); + if (s->is_uncompressed) { + s->state = BROTLI_STATE_UNCOMPRESSED; + break; + } + s->state = BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER; + /* Fall through. */ + + case BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER: { + BrotliMetablockHeaderArena* h = &s->arena.header; + s->loop_counter = 0; + /* Initialize compressed metablock header arena. */ + h->sub_loop_counter = 0; + /* Make small negative indexes addressable. */ + h->symbol_lists = + &h->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1]; + h->substate_huffman = BROTLI_STATE_HUFFMAN_NONE; + h->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE; + h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE; + s->state = BROTLI_STATE_HUFFMAN_CODE_0; + } + /* Fall through. */ + + case BROTLI_STATE_HUFFMAN_CODE_0: + if (s->loop_counter >= 3) { + s->state = BROTLI_STATE_METABLOCK_HEADER_2; + break; + } + /* Reads 1..11 bits. */ + result = DecodeVarLenUint8(s, br, &s->num_block_types[s->loop_counter]); + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + s->num_block_types[s->loop_counter]++; + BROTLI_LOG_UINT(s->num_block_types[s->loop_counter]); + if (s->num_block_types[s->loop_counter] < 2) { + s->loop_counter++; + break; + } + s->state = BROTLI_STATE_HUFFMAN_CODE_1; + /* Fall through. */ + + case BROTLI_STATE_HUFFMAN_CODE_1: { + brotli_reg_t alphabet_size = s->num_block_types[s->loop_counter] + 2; + int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258; + result = ReadHuffmanCode(alphabet_size, alphabet_size, + &s->block_type_trees[tree_offset], NULL, s); + if (result != BROTLI_DECODER_SUCCESS) break; + s->state = BROTLI_STATE_HUFFMAN_CODE_2; + } + /* Fall through. */ + + case BROTLI_STATE_HUFFMAN_CODE_2: { + brotli_reg_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS; + int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26; + result = ReadHuffmanCode(alphabet_size, alphabet_size, + &s->block_len_trees[tree_offset], NULL, s); + if (result != BROTLI_DECODER_SUCCESS) break; + s->state = BROTLI_STATE_HUFFMAN_CODE_3; + } + /* Fall through. */ + + case BROTLI_STATE_HUFFMAN_CODE_3: { + int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26; + if (!SafeReadBlockLength(s, &s->block_length[s->loop_counter], + &s->block_len_trees[tree_offset], br)) { + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + break; + } + BROTLI_LOG_UINT(s->block_length[s->loop_counter]); + s->loop_counter++; + s->state = BROTLI_STATE_HUFFMAN_CODE_0; + break; + } + + case BROTLI_STATE_UNCOMPRESSED: { + result = CopyUncompressedBlockToOutput( + available_out, next_out, total_out, s); + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + s->state = BROTLI_STATE_METABLOCK_DONE; + break; + } + + case BROTLI_STATE_METADATA: + result = SkipMetadataBlock(s); + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + s->state = BROTLI_STATE_METABLOCK_DONE; + break; + + case BROTLI_STATE_METABLOCK_HEADER_2: { + brotli_reg_t bits; + if (!BrotliSafeReadBits(br, 6, &bits)) { + result = BROTLI_DECODER_NEEDS_MORE_INPUT; + break; + } + s->distance_postfix_bits = bits & BitMask(2); + bits >>= 2; + s->num_direct_distance_codes = bits << s->distance_postfix_bits; + BROTLI_LOG_UINT(s->num_direct_distance_codes); + BROTLI_LOG_UINT(s->distance_postfix_bits); + s->context_modes = + (uint8_t*)BROTLI_DECODER_ALLOC(s, (size_t)s->num_block_types[0]); + if (s->context_modes == 0) { + result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_CONTEXT_MODES); + break; + } + s->loop_counter = 0; + s->state = BROTLI_STATE_CONTEXT_MODES; + } + /* Fall through. */ + + case BROTLI_STATE_CONTEXT_MODES: + result = ReadContextModes(s); + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + s->state = BROTLI_STATE_CONTEXT_MAP_1; + /* Fall through. */ + + case BROTLI_STATE_CONTEXT_MAP_1: + result = DecodeContextMap( + s->num_block_types[0] << BROTLI_LITERAL_CONTEXT_BITS, + &s->num_literal_htrees, &s->context_map, s); + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + DetectTrivialLiteralBlockTypes(s); + s->state = BROTLI_STATE_CONTEXT_MAP_2; + /* Fall through. */ + + case BROTLI_STATE_CONTEXT_MAP_2: { + brotli_reg_t npostfix = s->distance_postfix_bits; + brotli_reg_t ndirect = s->num_direct_distance_codes; + brotli_reg_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE( + npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS); + brotli_reg_t distance_alphabet_size_limit = distance_alphabet_size_max; + BROTLI_BOOL allocation_success = BROTLI_TRUE; + if (s->large_window) { + BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit( + BROTLI_MAX_ALLOWED_DISTANCE, (uint32_t)npostfix, + (uint32_t)ndirect); + distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE( + npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS); + distance_alphabet_size_limit = limit.max_alphabet_size; + } + result = DecodeContextMap( + s->num_block_types[2] << BROTLI_DISTANCE_CONTEXT_BITS, + &s->num_dist_htrees, &s->dist_context_map, s); + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + allocation_success &= BrotliDecoderHuffmanTreeGroupInit( + s, &s->literal_hgroup, BROTLI_NUM_LITERAL_SYMBOLS, + BROTLI_NUM_LITERAL_SYMBOLS, s->num_literal_htrees); + allocation_success &= BrotliDecoderHuffmanTreeGroupInit( + s, &s->insert_copy_hgroup, BROTLI_NUM_COMMAND_SYMBOLS, + BROTLI_NUM_COMMAND_SYMBOLS, s->num_block_types[1]); + allocation_success &= BrotliDecoderHuffmanTreeGroupInit( + s, &s->distance_hgroup, distance_alphabet_size_max, + distance_alphabet_size_limit, s->num_dist_htrees); + if (!allocation_success) { + return BROTLI_SAVE_ERROR_CODE( + BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_TREE_GROUPS)); + } + s->loop_counter = 0; + s->state = BROTLI_STATE_TREE_GROUP; + } + /* Fall through. */ + + case BROTLI_STATE_TREE_GROUP: { + HuffmanTreeGroup* hgroup = NULL; + switch (s->loop_counter) { + case 0: hgroup = &s->literal_hgroup; break; + case 1: hgroup = &s->insert_copy_hgroup; break; + case 2: hgroup = &s->distance_hgroup; break; + default: return BROTLI_SAVE_ERROR_CODE(BROTLI_FAILURE( + BROTLI_DECODER_ERROR_UNREACHABLE)); /* COV_NF_LINE */ + } + result = HuffmanTreeGroupDecode(hgroup, s); + if (result != BROTLI_DECODER_SUCCESS) break; + s->loop_counter++; + if (s->loop_counter < 3) { + break; + } + s->state = BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY; + } + /* Fall through. */ + + case BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY: + PrepareLiteralDecoding(s); + s->dist_context_map_slice = s->dist_context_map; + s->htree_command = s->insert_copy_hgroup.htrees[0]; + if (!BrotliEnsureRingBuffer(s)) { + result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_ALLOC_RING_BUFFER_2); + break; + } + CalculateDistanceLut(s); + s->state = BROTLI_STATE_COMMAND_BEGIN; + /* Fall through. */ + + case BROTLI_STATE_COMMAND_BEGIN: + /* Fall through. */ + case BROTLI_STATE_COMMAND_INNER: + /* Fall through. */ + case BROTLI_STATE_COMMAND_POST_DECODE_LITERALS: + /* Fall through. */ + case BROTLI_STATE_COMMAND_POST_WRAP_COPY: + result = ProcessCommands(s); + if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) { + result = SafeProcessCommands(s); + } + break; + + case BROTLI_STATE_COMMAND_INNER_WRITE: + /* Fall through. */ + case BROTLI_STATE_COMMAND_POST_WRITE_1: + /* Fall through. */ + case BROTLI_STATE_COMMAND_POST_WRITE_2: + result = WriteRingBuffer( + s, available_out, next_out, total_out, BROTLI_FALSE); + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + WrapRingBuffer(s); + if (s->ringbuffer_size == 1 << s->window_bits) { + s->max_distance = s->max_backward_distance; + } + if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) { + BrotliDecoderCompoundDictionary* addon = s->compound_dictionary; + if (addon && (addon->br_length != addon->br_copied)) { + s->pos += CopyFromCompoundDictionary(s, s->pos); + if (s->pos >= s->ringbuffer_size) continue; + } + if (s->meta_block_remaining_len == 0) { + /* Next metablock, if any. */ + s->state = BROTLI_STATE_METABLOCK_DONE; + } else { + s->state = BROTLI_STATE_COMMAND_BEGIN; + } + break; + } else if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_2) { + s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY; + } else { /* BROTLI_STATE_COMMAND_INNER_WRITE */ + if (s->loop_counter == 0) { + if (s->meta_block_remaining_len == 0) { + s->state = BROTLI_STATE_METABLOCK_DONE; + } else { + s->state = BROTLI_STATE_COMMAND_POST_DECODE_LITERALS; + } + break; + } + s->state = BROTLI_STATE_COMMAND_INNER; + } + break; + + case BROTLI_STATE_METABLOCK_DONE: + if (s->meta_block_remaining_len < 0) { + result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_2); + break; + } + BrotliDecoderStateCleanupAfterMetablock(s); + if (!s->is_last_metablock) { + s->state = BROTLI_STATE_METABLOCK_BEGIN; + break; + } + if (!BrotliJumpToByteBoundary(br)) { + result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_PADDING_2); + break; + } + if (s->buffer_length == 0) { + BrotliBitReaderUnload(br); + *available_in = BrotliBitReaderGetAvailIn(br); + *next_in = br->next_in; + } + s->state = BROTLI_STATE_DONE; + /* Fall through. */ + + case BROTLI_STATE_DONE: + if (s->ringbuffer != 0) { + result = WriteRingBuffer( + s, available_out, next_out, total_out, BROTLI_TRUE); + if (result != BROTLI_DECODER_SUCCESS) { + break; + } + } + return BROTLI_SAVE_ERROR_CODE(result); + } + } + return BROTLI_SAVE_ERROR_CODE(result); +#undef BROTLI_SAVE_ERROR_CODE +} + +BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s) { + /* After unrecoverable error remaining output is considered nonsensical. */ + if ((int)s->error_code < 0) { + return BROTLI_FALSE; + } + return TO_BROTLI_BOOL( + s->ringbuffer != 0 && UnwrittenBytes(s, BROTLI_FALSE) != 0); +} + +const uint8_t* BrotliDecoderTakeOutput(BrotliDecoderState* s, size_t* size) { + uint8_t* result = 0; + size_t available_out = *size ? *size : 1u << 24; + size_t requested_out = available_out; + BrotliDecoderErrorCode status; + if ((s->ringbuffer == 0) || ((int)s->error_code < 0)) { + *size = 0; + return 0; + } + WrapRingBuffer(s); + status = WriteRingBuffer(s, &available_out, &result, 0, BROTLI_TRUE); + /* Either WriteRingBuffer returns those "success" codes... */ + if (status == BROTLI_DECODER_SUCCESS || + status == BROTLI_DECODER_NEEDS_MORE_OUTPUT) { + *size = requested_out - available_out; + } else { + /* ... or stream is broken. Normally this should be caught by + BrotliDecoderDecompressStream, this is just a safeguard. */ + if ((int)status < 0) SaveErrorCode(s, status, 0); + *size = 0; + result = 0; + } + return result; +} + +BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* s) { + return TO_BROTLI_BOOL(s->state != BROTLI_STATE_UNINITED || + BrotliGetAvailableBits(&s->br) != 0); +} + +BROTLI_BOOL BrotliDecoderIsFinished(const BrotliDecoderState* s) { + return TO_BROTLI_BOOL(s->state == BROTLI_STATE_DONE) && + !BrotliDecoderHasMoreOutput(s); +} + +BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) { + return (BrotliDecoderErrorCode)s->error_code; +} + +const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) { + switch (c) { +#define BROTLI_ERROR_CODE_CASE_(PREFIX, NAME, CODE) \ + case BROTLI_DECODER ## PREFIX ## NAME: return #PREFIX #NAME; +#define BROTLI_NOTHING_ + BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_CASE_, BROTLI_NOTHING_) +#undef BROTLI_ERROR_CODE_CASE_ +#undef BROTLI_NOTHING_ + default: return "INVALID"; + } +} + +uint32_t BrotliDecoderVersion(void) { + return BROTLI_VERSION; +} + +void BrotliDecoderSetMetadataCallbacks( + BrotliDecoderState* state, + brotli_decoder_metadata_start_func start_func, + brotli_decoder_metadata_chunk_func chunk_func, void* opaque) { + state->metadata_start_func = start_func; + state->metadata_chunk_func = chunk_func; + state->metadata_callback_opaque = opaque; +} + +/* Escalate internal functions visibility; for testing purposes only. */ +#if defined(BROTLI_TEST) +BROTLI_BOOL BrotliSafeReadSymbolForTest( + const HuffmanCode*, BrotliBitReader*, brotli_reg_t*); +BROTLI_BOOL BrotliSafeReadSymbolForTest( + const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) { + return SafeReadSymbol(table, br, result); +} +void BrotliInverseMoveToFrontTransformForTest( + uint8_t*, brotli_reg_t, BrotliDecoderState*); +void BrotliInverseMoveToFrontTransformForTest( + uint8_t* v, brotli_reg_t l, BrotliDecoderState* s) { + InverseMoveToFrontTransform(v, l, s); +} +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/dec/huffman.c b/packages/runtime/vendor/brotli/c/dec/huffman.c new file mode 100644 index 000000000..06486cf81 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/huffman.c @@ -0,0 +1,339 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Utilities for building Huffman decoding tables. */ + +#include "huffman.h" + +#include "../common/constants.h" +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define BROTLI_REVERSE_BITS_MAX 8 + +#if defined(BROTLI_RBIT) +#define BROTLI_REVERSE_BITS_BASE \ + ((sizeof(brotli_reg_t) << 3) - BROTLI_REVERSE_BITS_MAX) +#else +#define BROTLI_REVERSE_BITS_BASE 0 +static BROTLI_MODEL("small") +uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = { + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF +}; +#endif /* BROTLI_RBIT */ + +#define BROTLI_REVERSE_BITS_LOWEST \ + ((brotli_reg_t)1 << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE)) + +/* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX), + where reverse(value, len) is the bit-wise reversal of the len least + significant bits of value. */ +static BROTLI_INLINE brotli_reg_t BrotliReverseBits(brotli_reg_t num) { +#if defined(BROTLI_RBIT) + return BROTLI_RBIT(num); +#else + return kReverseBits[num]; +#endif +} + +/* Stores code in table[0], table[step], table[2*step], ..., table[end] */ +/* Assumes that end is an integer multiple of step */ +static BROTLI_INLINE void ReplicateValue(HuffmanCode* table, + int step, int end, + HuffmanCode code) { + do { + end -= step; + table[end] = code; + } while (end > 0); +} + +/* Returns the table width of the next 2nd level table. |count| is the histogram + of bit lengths for the remaining symbols, |len| is the code length of the + next processed symbol. */ +static BROTLI_INLINE int NextTableBitSize(const uint16_t* const count, + int len, int root_bits) { + int left = 1 << (len - root_bits); + while (len < BROTLI_HUFFMAN_MAX_CODE_LENGTH) { + left -= count[len]; + if (left <= 0) break; + ++len; + left <<= 1; + } + return len - root_bits; +} + +void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table, + const uint8_t* const code_lengths, + uint16_t* count) { + HuffmanCode code; /* current table entry */ + int symbol; /* symbol index in original or sorted table */ + brotli_reg_t key; /* prefix code */ + brotli_reg_t key_step; /* prefix code addend */ + int step; /* step size to replicate values in current table */ + int table_size; /* size of current table */ + int sorted[BROTLI_CODE_LENGTH_CODES]; /* symbols sorted by code length */ + /* offsets in sorted table for each length */ + int offset[BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1]; + int bits; + int bits_count; + BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <= + BROTLI_REVERSE_BITS_MAX); + BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5); + + /* Generate offsets into sorted symbol table by code length. */ + symbol = -1; + bits = 1; + /* BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH == 5 */ + BROTLI_REPEAT_5({ + symbol += count[bits]; + offset[bits] = symbol; + bits++; + }); + /* Symbols with code length 0 are placed after all other symbols. */ + offset[0] = BROTLI_CODE_LENGTH_CODES - 1; + + /* Sort symbols by length, by symbol order within each length. */ + symbol = BROTLI_CODE_LENGTH_CODES; + do { + BROTLI_REPEAT_6({ + symbol--; + sorted[offset[code_lengths[symbol]]--] = symbol; + }); + } while (symbol != 0); + + table_size = 1 << BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH; + + /* Special case: all symbols but one have 0 code length. */ + if (offset[0] == 0) { + code = ConstructHuffmanCode(0, (uint16_t)sorted[0]); + for (key = 0; key < (brotli_reg_t)table_size; ++key) { + table[key] = code; + } + return; + } + + /* Fill in table. */ + key = 0; + key_step = BROTLI_REVERSE_BITS_LOWEST; + symbol = 0; + bits = 1; + step = 2; + do { + for (bits_count = count[bits]; bits_count != 0; --bits_count) { + code = ConstructHuffmanCode((uint8_t)bits, (uint16_t)sorted[symbol++]); + ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code); + key += key_step; + } + step <<= 1; + key_step >>= 1; + } while (++bits <= BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH); +} + +uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table, + int root_bits, + const uint16_t* const symbol_lists, + uint16_t* count) { + HuffmanCode code; /* current table entry */ + HuffmanCode* table; /* next available space in table */ + int len; /* current code length */ + int symbol; /* symbol index in original or sorted table */ + brotli_reg_t key; /* prefix code */ + brotli_reg_t key_step; /* prefix code addend */ + brotli_reg_t sub_key; /* 2nd level table prefix code */ + brotli_reg_t sub_key_step; /* 2nd level table prefix code addend */ + int step; /* step size to replicate values in current table */ + int table_bits; /* key length of current table */ + int table_size; /* size of current table */ + int total_size; /* sum of root table size and 2nd level table sizes */ + int max_length = -1; + int bits; + int bits_count; + + BROTLI_DCHECK(root_bits <= BROTLI_REVERSE_BITS_MAX); + BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH - root_bits <= + BROTLI_REVERSE_BITS_MAX); + + while (symbol_lists[max_length] == 0xFFFF) max_length--; + max_length += BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1; + + table = root_table; + table_bits = root_bits; + table_size = 1 << table_bits; + total_size = table_size; + + /* Fill in the root table. Reduce the table size to if possible, + and create the repetitions by memcpy. */ + if (table_bits > max_length) { + table_bits = max_length; + table_size = 1 << table_bits; + } + key = 0; + key_step = BROTLI_REVERSE_BITS_LOWEST; + bits = 1; + step = 2; + do { + symbol = bits - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1); + for (bits_count = count[bits]; bits_count != 0; --bits_count) { + symbol = symbol_lists[symbol]; + code = ConstructHuffmanCode((uint8_t)bits, (uint16_t)symbol); + ReplicateValue(&table[BrotliReverseBits(key)], step, table_size, code); + key += key_step; + } + step <<= 1; + key_step >>= 1; + } while (++bits <= table_bits); + + /* If root_bits != table_bits then replicate to fill the remaining slots. */ + while (total_size != table_size) { + memcpy(&table[table_size], &table[0], + (size_t)table_size * sizeof(table[0])); + table_size <<= 1; + } + + /* Fill in 2nd level tables and add pointers to root table. */ + key_step = BROTLI_REVERSE_BITS_LOWEST >> (root_bits - 1); + sub_key = (BROTLI_REVERSE_BITS_LOWEST << 1); + sub_key_step = BROTLI_REVERSE_BITS_LOWEST; + for (len = root_bits + 1, step = 2; len <= max_length; ++len) { + symbol = len - (BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1); + for (; count[len] != 0; --count[len]) { + if (sub_key == (BROTLI_REVERSE_BITS_LOWEST << 1U)) { + table += table_size; + table_bits = NextTableBitSize(count, len, root_bits); + table_size = 1 << table_bits; + total_size += table_size; + sub_key = BrotliReverseBits(key); + key += key_step; + root_table[sub_key] = ConstructHuffmanCode( + (uint8_t)(table_bits + root_bits), + (uint16_t)(((size_t)(table - root_table)) - sub_key)); + sub_key = 0; + } + symbol = symbol_lists[symbol]; + code = ConstructHuffmanCode((uint8_t)(len - root_bits), (uint16_t)symbol); + ReplicateValue( + &table[BrotliReverseBits(sub_key)], step, table_size, code); + sub_key += sub_key_step; + } + step <<= 1; + sub_key_step >>= 1; + } + return (uint32_t)total_size; +} + +uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table, + int root_bits, + uint16_t* val, + uint32_t num_symbols) { + uint32_t table_size = 1; + const uint32_t goal_size = 1U << root_bits; + switch (num_symbols) { + case 0: + table[0] = ConstructHuffmanCode(0, val[0]); + break; + case 1: + if (val[1] > val[0]) { + table[0] = ConstructHuffmanCode(1, val[0]); + table[1] = ConstructHuffmanCode(1, val[1]); + } else { + table[0] = ConstructHuffmanCode(1, val[1]); + table[1] = ConstructHuffmanCode(1, val[0]); + } + table_size = 2; + break; + case 2: + table[0] = ConstructHuffmanCode(1, val[0]); + table[2] = ConstructHuffmanCode(1, val[0]); + if (val[2] > val[1]) { + table[1] = ConstructHuffmanCode(2, val[1]); + table[3] = ConstructHuffmanCode(2, val[2]); + } else { + table[1] = ConstructHuffmanCode(2, val[2]); + table[3] = ConstructHuffmanCode(2, val[1]); + } + table_size = 4; + break; + case 3: { + int i, k; + for (i = 0; i < 3; ++i) { + for (k = i + 1; k < 4; ++k) { + if (val[k] < val[i]) { + uint16_t t = val[k]; + val[k] = val[i]; + val[i] = t; + } + } + } + table[0] = ConstructHuffmanCode(2, val[0]); + table[2] = ConstructHuffmanCode(2, val[1]); + table[1] = ConstructHuffmanCode(2, val[2]); + table[3] = ConstructHuffmanCode(2, val[3]); + table_size = 4; + break; + } + case 4: { + if (val[3] < val[2]) { + uint16_t t = val[3]; + val[3] = val[2]; + val[2] = t; + } + table[0] = ConstructHuffmanCode(1, val[0]); + table[1] = ConstructHuffmanCode(2, val[1]); + table[2] = ConstructHuffmanCode(1, val[0]); + table[3] = ConstructHuffmanCode(3, val[2]); + table[4] = ConstructHuffmanCode(1, val[0]); + table[5] = ConstructHuffmanCode(2, val[1]); + table[6] = ConstructHuffmanCode(1, val[0]); + table[7] = ConstructHuffmanCode(3, val[3]); + table_size = 8; + break; + } + } + while (table_size != goal_size) { + memcpy(&table[table_size], &table[0], + (size_t)table_size * sizeof(table[0])); + table_size <<= 1; + } + return goal_size; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/dec/huffman.h b/packages/runtime/vendor/brotli/c/dec/huffman.h new file mode 100644 index 000000000..53daf600e --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/huffman.h @@ -0,0 +1,120 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Utilities for building Huffman decoding tables. */ + +#ifndef BROTLI_DEC_HUFFMAN_H_ +#define BROTLI_DEC_HUFFMAN_H_ + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15 + +/* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */ +#define BROTLI_HUFFMAN_MAX_SIZE_26 396 +/* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */ +#define BROTLI_HUFFMAN_MAX_SIZE_258 632 +/* BROTLI_MAX_CONTEXT_MAP_SYMBOLS == 272 */ +#define BROTLI_HUFFMAN_MAX_SIZE_272 646 + +#define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5 + +#if ((defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_32)) && \ + BROTLI_GNUC_HAS_ATTRIBUTE(aligned, 2, 7, 0)) +#define BROTLI_HUFFMAN_CODE_FAST_LOAD +#endif + +#if !defined(BROTLI_HUFFMAN_CODE_FAST_LOAD) +/* Do not create this struct directly - use the ConstructHuffmanCode + * constructor below! */ +typedef struct { + uint8_t bits; /* number of bits used for this symbol */ + uint16_t value; /* symbol value or table offset */ +} HuffmanCode; + +static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits, + const uint16_t value) { + HuffmanCode h; + h.bits = bits; + h.value = value; + return h; +} + +/* Please use the following macros to optimize HuffmanCode accesses in hot + * paths. + * + * For example, assuming |table| contains a HuffmanCode pointer: + * + * BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table); + * BROTLI_HC_ADJUST_TABLE_INDEX(table, index_into_table); + * *bits = BROTLI_HC_GET_BITS(table); + * *value = BROTLI_HC_GET_VALUE(table); + * BROTLI_HC_ADJUST_TABLE_INDEX(table, offset); + * *bits2 = BROTLI_HC_GET_BITS(table); + * *value2 = BROTLI_HC_GET_VALUE(table); + * + */ + +#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) +#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V) + +/* These must be given a HuffmanCode pointer! */ +#define BROTLI_HC_FAST_LOAD_BITS(H) (H->bits) +#define BROTLI_HC_FAST_LOAD_VALUE(H) (H->value) + +#else /* BROTLI_HUFFMAN_CODE_FAST_LOAD */ + +typedef BROTLI_ALIGNED(4) uint32_t HuffmanCode; + +static BROTLI_INLINE HuffmanCode ConstructHuffmanCode(const uint8_t bits, + const uint16_t value) { + return (HuffmanCode) ((value & 0xFFFF) << 16) | (bits & 0xFF); +} + +#define BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(H) uint32_t __fastload_##H = (*H) +#define BROTLI_HC_ADJUST_TABLE_INDEX(H, V) H += (V); __fastload_##H = (*H) + +/* These must be given a HuffmanCode pointer! */ +#define BROTLI_HC_FAST_LOAD_BITS(H) ((__fastload_##H) & 0xFF) +#define BROTLI_HC_FAST_LOAD_VALUE(H) ((__fastload_##H) >> 16) +#endif /* BROTLI_HUFFMAN_CODE_FAST_LOAD */ + +/* Builds Huffman lookup table assuming code lengths are in symbol order. */ +BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table, + const uint8_t* const code_lengths, uint16_t* count); + +/* Builds Huffman lookup table assuming code lengths are in symbol order. + Returns size of resulting table. */ +BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table, + int root_bits, const uint16_t* const symbol_lists, uint16_t* count); + +/* Builds a simple Huffman table. The |num_symbols| parameter is to be + interpreted as follows: 0 means 1 symbol, 1 means 2 symbols, + 2 means 3 symbols, 3 means 4 symbols with lengths [2, 2, 2, 2], + 4 means 4 symbols with lengths [1, 2, 3, 3]. */ +BROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table, + int root_bits, uint16_t* symbols, uint32_t num_symbols); + +/* Contains a collection of Huffman trees with the same alphabet size. */ +/* alphabet_size_limit is needed due to simple codes, since + log2(alphabet_size_max) could be greater than log2(alphabet_size_limit). */ +typedef struct { + HuffmanCode** htrees; + HuffmanCode* codes; + uint16_t alphabet_size_max; + uint16_t alphabet_size_limit; + uint16_t num_htrees; +} HuffmanTreeGroup; + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_HUFFMAN_H_ */ diff --git a/packages/runtime/vendor/brotli/c/dec/prefix.c b/packages/runtime/vendor/brotli/c/dec/prefix.c new file mode 100644 index 000000000..ce3998f24 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/prefix.c @@ -0,0 +1,67 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "prefix.h" + +#include "../common/platform.h" /* IWYU pragma: keep */ +#include "../common/static_init.h" + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +#include "../common/constants.h" +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_NONE) +/* Embed kCmdLut. */ +#include "prefix_inc.h" +#else +BROTLI_COLD BROTLI_BOOL BrotliDecoderInitCmdLut(CmdLutElement* items) { + static const uint8_t kInsertLengthExtraBits[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, + 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0C, 0x0E, 0x18}; + static const uint8_t kCopyLengthExtraBits[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, + 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x18}; + static const uint8_t kCellPos[11] = {0, 1, 0, 1, 8, 9, 2, 16, 10, 17, 18}; + + uint16_t insert_length_offsets[24]; + uint16_t copy_length_offsets[24]; + insert_length_offsets[0] = 0; + copy_length_offsets[0] = 2; + for (size_t i = 0; i < 23; ++i) { + insert_length_offsets[i + 1] = + insert_length_offsets[i] + (uint16_t)(1u << kInsertLengthExtraBits[i]); + copy_length_offsets[i + 1] = + copy_length_offsets[i] + (uint16_t)(1u << kCopyLengthExtraBits[i]); + } + + for (size_t symbol = 0; symbol < BROTLI_NUM_COMMAND_SYMBOLS; ++symbol) { + CmdLutElement* item = items + symbol; + const size_t cell_idx = symbol >> 6; + const size_t cell_pos = kCellPos[cell_idx]; + const size_t copy_code = ((cell_pos << 3) & 0x18) + (symbol & 0x7); + const uint16_t copy_len_offset = copy_length_offsets[copy_code]; + const size_t insert_code = (cell_pos & 0x18) + ((symbol >> 3) & 0x7); + item->copy_len_extra_bits = kCopyLengthExtraBits[copy_code]; + item->context = (copy_len_offset > 4) ? 3 : ((uint8_t)copy_len_offset - 2); + item->copy_len_offset = copy_len_offset; + item->distance_code = (cell_idx >= 2) ? -1 : 0; + item->insert_len_extra_bits = kInsertLengthExtraBits[insert_code]; + item->insert_len_offset = insert_length_offsets[insert_code]; + } + return BROTLI_TRUE; +} + +BROTLI_MODEL("small") +CmdLutElement kCmdLut[BROTLI_NUM_COMMAND_SYMBOLS]; +#endif /* BROTLI_STATIC_INIT */ + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/dec/prefix.h b/packages/runtime/vendor/brotli/c/dec/prefix.h new file mode 100644 index 000000000..f45b8be40 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/prefix.h @@ -0,0 +1,43 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Lookup tables to map prefix codes to value ranges. This is used during + decoding of the block lengths, literal insertion lengths and copy lengths. */ + +#ifndef BROTLI_DEC_PREFIX_H_ +#define BROTLI_DEC_PREFIX_H_ + +#include "../common/constants.h" +#include "../common/platform.h" /* IWYU pragma: keep */ +#include "../common/static_init.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct CmdLutElement { + uint8_t insert_len_extra_bits; + uint8_t copy_len_extra_bits; + int8_t distance_code; + uint8_t context; + uint16_t insert_len_offset; + uint16_t copy_len_offset; +} CmdLutElement; + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_NONE) +BROTLI_INTERNAL extern const BROTLI_MODEL("small") + CmdLutElement kCmdLut[BROTLI_NUM_COMMAND_SYMBOLS]; +#else +BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderInitCmdLut(CmdLutElement* items); +BROTLI_INTERNAL extern BROTLI_MODEL("small") + CmdLutElement kCmdLut[BROTLI_NUM_COMMAND_SYMBOLS]; +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_PREFIX_H_ */ diff --git a/packages/runtime/vendor/brotli/c/dec/prefix_inc.h b/packages/runtime/vendor/brotli/c/dec/prefix_inc.h new file mode 100644 index 000000000..91d81b846 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/prefix_inc.h @@ -0,0 +1,707 @@ +const BROTLI_MODEL("small") +CmdLutElement kCmdLut[BROTLI_NUM_COMMAND_SYMBOLS] = { + { 0x00, 0x00, 0, 0x00, 0x0000, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0000, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0000, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0000, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0001, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0001, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0001, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0001, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0002, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0002, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0002, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0002, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0003, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0003, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0003, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0003, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0004, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0004, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0004, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0004, 0x0009 }, + { 0x00, 0x00, 0, 0x00, 0x0005, 0x0002 }, + { 0x00, 0x00, 0, 0x01, 0x0005, 0x0003 }, + { 0x00, 0x00, 0, 0x02, 0x0005, 0x0004 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0005 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0006 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0007 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0008 }, + { 0x00, 0x00, 0, 0x03, 0x0005, 0x0009 }, + { 0x01, 0x00, 0, 0x00, 0x0006, 0x0002 }, + { 0x01, 0x00, 0, 0x01, 0x0006, 0x0003 }, + { 0x01, 0x00, 0, 0x02, 0x0006, 0x0004 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0005 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0006 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0007 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0008 }, + { 0x01, 0x00, 0, 0x03, 0x0006, 0x0009 }, + { 0x01, 0x00, 0, 0x00, 0x0008, 0x0002 }, + { 0x01, 0x00, 0, 0x01, 0x0008, 0x0003 }, + { 0x01, 0x00, 0, 0x02, 0x0008, 0x0004 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0005 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0006 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0007 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0008 }, + { 0x01, 0x00, 0, 0x03, 0x0008, 0x0009 }, + { 0x00, 0x01, 0, 0x03, 0x0000, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0000, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0000, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0000, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0000, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0000, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0000, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0000, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0001, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0001, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0001, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0001, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0001, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0001, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0001, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0001, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0002, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0002, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0002, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0002, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0002, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0002, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0002, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0002, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0003, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0003, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0003, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0003, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0003, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0003, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0003, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0003, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0004, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0004, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0004, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0004, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0004, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0004, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0004, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0004, 0x0036 }, + { 0x00, 0x01, 0, 0x03, 0x0005, 0x000a }, + { 0x00, 0x01, 0, 0x03, 0x0005, 0x000c }, + { 0x00, 0x02, 0, 0x03, 0x0005, 0x000e }, + { 0x00, 0x02, 0, 0x03, 0x0005, 0x0012 }, + { 0x00, 0x03, 0, 0x03, 0x0005, 0x0016 }, + { 0x00, 0x03, 0, 0x03, 0x0005, 0x001e }, + { 0x00, 0x04, 0, 0x03, 0x0005, 0x0026 }, + { 0x00, 0x04, 0, 0x03, 0x0005, 0x0036 }, + { 0x01, 0x01, 0, 0x03, 0x0006, 0x000a }, + { 0x01, 0x01, 0, 0x03, 0x0006, 0x000c }, + { 0x01, 0x02, 0, 0x03, 0x0006, 0x000e }, + { 0x01, 0x02, 0, 0x03, 0x0006, 0x0012 }, + { 0x01, 0x03, 0, 0x03, 0x0006, 0x0016 }, + { 0x01, 0x03, 0, 0x03, 0x0006, 0x001e }, + { 0x01, 0x04, 0, 0x03, 0x0006, 0x0026 }, + { 0x01, 0x04, 0, 0x03, 0x0006, 0x0036 }, + { 0x01, 0x01, 0, 0x03, 0x0008, 0x000a }, + { 0x01, 0x01, 0, 0x03, 0x0008, 0x000c }, + { 0x01, 0x02, 0, 0x03, 0x0008, 0x000e }, + { 0x01, 0x02, 0, 0x03, 0x0008, 0x0012 }, + { 0x01, 0x03, 0, 0x03, 0x0008, 0x0016 }, + { 0x01, 0x03, 0, 0x03, 0x0008, 0x001e }, + { 0x01, 0x04, 0, 0x03, 0x0008, 0x0026 }, + { 0x01, 0x04, 0, 0x03, 0x0008, 0x0036 }, + { 0x00, 0x00, -1, 0x00, 0x0000, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0000, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0000, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0000, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0001, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0001, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0001, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0001, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0002, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0002, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0002, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0002, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0003, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0003, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0003, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0003, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0004, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0004, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0004, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0004, 0x0009 }, + { 0x00, 0x00, -1, 0x00, 0x0005, 0x0002 }, + { 0x00, 0x00, -1, 0x01, 0x0005, 0x0003 }, + { 0x00, 0x00, -1, 0x02, 0x0005, 0x0004 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0005 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0006 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0007 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0008 }, + { 0x00, 0x00, -1, 0x03, 0x0005, 0x0009 }, + { 0x01, 0x00, -1, 0x00, 0x0006, 0x0002 }, + { 0x01, 0x00, -1, 0x01, 0x0006, 0x0003 }, + { 0x01, 0x00, -1, 0x02, 0x0006, 0x0004 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0005 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0006 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0007 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0008 }, + { 0x01, 0x00, -1, 0x03, 0x0006, 0x0009 }, + { 0x01, 0x00, -1, 0x00, 0x0008, 0x0002 }, + { 0x01, 0x00, -1, 0x01, 0x0008, 0x0003 }, + { 0x01, 0x00, -1, 0x02, 0x0008, 0x0004 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0005 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0006 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0007 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0008 }, + { 0x01, 0x00, -1, 0x03, 0x0008, 0x0009 }, + { 0x00, 0x01, -1, 0x03, 0x0000, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0000, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0000, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0000, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0000, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0000, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0000, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0000, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0001, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0001, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0001, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0001, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0001, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0001, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0001, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0001, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0002, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0002, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0002, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0002, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0002, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0002, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0002, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0002, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0003, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0003, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0003, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0003, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0003, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0003, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0003, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0003, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0004, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0004, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0004, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0004, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0004, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0004, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0004, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0004, 0x0036 }, + { 0x00, 0x01, -1, 0x03, 0x0005, 0x000a }, + { 0x00, 0x01, -1, 0x03, 0x0005, 0x000c }, + { 0x00, 0x02, -1, 0x03, 0x0005, 0x000e }, + { 0x00, 0x02, -1, 0x03, 0x0005, 0x0012 }, + { 0x00, 0x03, -1, 0x03, 0x0005, 0x0016 }, + { 0x00, 0x03, -1, 0x03, 0x0005, 0x001e }, + { 0x00, 0x04, -1, 0x03, 0x0005, 0x0026 }, + { 0x00, 0x04, -1, 0x03, 0x0005, 0x0036 }, + { 0x01, 0x01, -1, 0x03, 0x0006, 0x000a }, + { 0x01, 0x01, -1, 0x03, 0x0006, 0x000c }, + { 0x01, 0x02, -1, 0x03, 0x0006, 0x000e }, + { 0x01, 0x02, -1, 0x03, 0x0006, 0x0012 }, + { 0x01, 0x03, -1, 0x03, 0x0006, 0x0016 }, + { 0x01, 0x03, -1, 0x03, 0x0006, 0x001e }, + { 0x01, 0x04, -1, 0x03, 0x0006, 0x0026 }, + { 0x01, 0x04, -1, 0x03, 0x0006, 0x0036 }, + { 0x01, 0x01, -1, 0x03, 0x0008, 0x000a }, + { 0x01, 0x01, -1, 0x03, 0x0008, 0x000c }, + { 0x01, 0x02, -1, 0x03, 0x0008, 0x000e }, + { 0x01, 0x02, -1, 0x03, 0x0008, 0x0012 }, + { 0x01, 0x03, -1, 0x03, 0x0008, 0x0016 }, + { 0x01, 0x03, -1, 0x03, 0x0008, 0x001e }, + { 0x01, 0x04, -1, 0x03, 0x0008, 0x0026 }, + { 0x01, 0x04, -1, 0x03, 0x0008, 0x0036 }, + { 0x02, 0x00, -1, 0x00, 0x000a, 0x0002 }, + { 0x02, 0x00, -1, 0x01, 0x000a, 0x0003 }, + { 0x02, 0x00, -1, 0x02, 0x000a, 0x0004 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0005 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0006 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0007 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0008 }, + { 0x02, 0x00, -1, 0x03, 0x000a, 0x0009 }, + { 0x02, 0x00, -1, 0x00, 0x000e, 0x0002 }, + { 0x02, 0x00, -1, 0x01, 0x000e, 0x0003 }, + { 0x02, 0x00, -1, 0x02, 0x000e, 0x0004 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0005 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0006 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0007 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0008 }, + { 0x02, 0x00, -1, 0x03, 0x000e, 0x0009 }, + { 0x03, 0x00, -1, 0x00, 0x0012, 0x0002 }, + { 0x03, 0x00, -1, 0x01, 0x0012, 0x0003 }, + { 0x03, 0x00, -1, 0x02, 0x0012, 0x0004 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0005 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0006 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0007 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0008 }, + { 0x03, 0x00, -1, 0x03, 0x0012, 0x0009 }, + { 0x03, 0x00, -1, 0x00, 0x001a, 0x0002 }, + { 0x03, 0x00, -1, 0x01, 0x001a, 0x0003 }, + { 0x03, 0x00, -1, 0x02, 0x001a, 0x0004 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0005 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0006 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0007 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0008 }, + { 0x03, 0x00, -1, 0x03, 0x001a, 0x0009 }, + { 0x04, 0x00, -1, 0x00, 0x0022, 0x0002 }, + { 0x04, 0x00, -1, 0x01, 0x0022, 0x0003 }, + { 0x04, 0x00, -1, 0x02, 0x0022, 0x0004 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0005 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0006 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0007 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0008 }, + { 0x04, 0x00, -1, 0x03, 0x0022, 0x0009 }, + { 0x04, 0x00, -1, 0x00, 0x0032, 0x0002 }, + { 0x04, 0x00, -1, 0x01, 0x0032, 0x0003 }, + { 0x04, 0x00, -1, 0x02, 0x0032, 0x0004 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0005 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0006 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0007 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0008 }, + { 0x04, 0x00, -1, 0x03, 0x0032, 0x0009 }, + { 0x05, 0x00, -1, 0x00, 0x0042, 0x0002 }, + { 0x05, 0x00, -1, 0x01, 0x0042, 0x0003 }, + { 0x05, 0x00, -1, 0x02, 0x0042, 0x0004 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0005 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0006 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0007 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0008 }, + { 0x05, 0x00, -1, 0x03, 0x0042, 0x0009 }, + { 0x05, 0x00, -1, 0x00, 0x0062, 0x0002 }, + { 0x05, 0x00, -1, 0x01, 0x0062, 0x0003 }, + { 0x05, 0x00, -1, 0x02, 0x0062, 0x0004 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0005 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0006 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0007 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0008 }, + { 0x05, 0x00, -1, 0x03, 0x0062, 0x0009 }, + { 0x02, 0x01, -1, 0x03, 0x000a, 0x000a }, + { 0x02, 0x01, -1, 0x03, 0x000a, 0x000c }, + { 0x02, 0x02, -1, 0x03, 0x000a, 0x000e }, + { 0x02, 0x02, -1, 0x03, 0x000a, 0x0012 }, + { 0x02, 0x03, -1, 0x03, 0x000a, 0x0016 }, + { 0x02, 0x03, -1, 0x03, 0x000a, 0x001e }, + { 0x02, 0x04, -1, 0x03, 0x000a, 0x0026 }, + { 0x02, 0x04, -1, 0x03, 0x000a, 0x0036 }, + { 0x02, 0x01, -1, 0x03, 0x000e, 0x000a }, + { 0x02, 0x01, -1, 0x03, 0x000e, 0x000c }, + { 0x02, 0x02, -1, 0x03, 0x000e, 0x000e }, + { 0x02, 0x02, -1, 0x03, 0x000e, 0x0012 }, + { 0x02, 0x03, -1, 0x03, 0x000e, 0x0016 }, + { 0x02, 0x03, -1, 0x03, 0x000e, 0x001e }, + { 0x02, 0x04, -1, 0x03, 0x000e, 0x0026 }, + { 0x02, 0x04, -1, 0x03, 0x000e, 0x0036 }, + { 0x03, 0x01, -1, 0x03, 0x0012, 0x000a }, + { 0x03, 0x01, -1, 0x03, 0x0012, 0x000c }, + { 0x03, 0x02, -1, 0x03, 0x0012, 0x000e }, + { 0x03, 0x02, -1, 0x03, 0x0012, 0x0012 }, + { 0x03, 0x03, -1, 0x03, 0x0012, 0x0016 }, + { 0x03, 0x03, -1, 0x03, 0x0012, 0x001e }, + { 0x03, 0x04, -1, 0x03, 0x0012, 0x0026 }, + { 0x03, 0x04, -1, 0x03, 0x0012, 0x0036 }, + { 0x03, 0x01, -1, 0x03, 0x001a, 0x000a }, + { 0x03, 0x01, -1, 0x03, 0x001a, 0x000c }, + { 0x03, 0x02, -1, 0x03, 0x001a, 0x000e }, + { 0x03, 0x02, -1, 0x03, 0x001a, 0x0012 }, + { 0x03, 0x03, -1, 0x03, 0x001a, 0x0016 }, + { 0x03, 0x03, -1, 0x03, 0x001a, 0x001e }, + { 0x03, 0x04, -1, 0x03, 0x001a, 0x0026 }, + { 0x03, 0x04, -1, 0x03, 0x001a, 0x0036 }, + { 0x04, 0x01, -1, 0x03, 0x0022, 0x000a }, + { 0x04, 0x01, -1, 0x03, 0x0022, 0x000c }, + { 0x04, 0x02, -1, 0x03, 0x0022, 0x000e }, + { 0x04, 0x02, -1, 0x03, 0x0022, 0x0012 }, + { 0x04, 0x03, -1, 0x03, 0x0022, 0x0016 }, + { 0x04, 0x03, -1, 0x03, 0x0022, 0x001e }, + { 0x04, 0x04, -1, 0x03, 0x0022, 0x0026 }, + { 0x04, 0x04, -1, 0x03, 0x0022, 0x0036 }, + { 0x04, 0x01, -1, 0x03, 0x0032, 0x000a }, + { 0x04, 0x01, -1, 0x03, 0x0032, 0x000c }, + { 0x04, 0x02, -1, 0x03, 0x0032, 0x000e }, + { 0x04, 0x02, -1, 0x03, 0x0032, 0x0012 }, + { 0x04, 0x03, -1, 0x03, 0x0032, 0x0016 }, + { 0x04, 0x03, -1, 0x03, 0x0032, 0x001e }, + { 0x04, 0x04, -1, 0x03, 0x0032, 0x0026 }, + { 0x04, 0x04, -1, 0x03, 0x0032, 0x0036 }, + { 0x05, 0x01, -1, 0x03, 0x0042, 0x000a }, + { 0x05, 0x01, -1, 0x03, 0x0042, 0x000c }, + { 0x05, 0x02, -1, 0x03, 0x0042, 0x000e }, + { 0x05, 0x02, -1, 0x03, 0x0042, 0x0012 }, + { 0x05, 0x03, -1, 0x03, 0x0042, 0x0016 }, + { 0x05, 0x03, -1, 0x03, 0x0042, 0x001e }, + { 0x05, 0x04, -1, 0x03, 0x0042, 0x0026 }, + { 0x05, 0x04, -1, 0x03, 0x0042, 0x0036 }, + { 0x05, 0x01, -1, 0x03, 0x0062, 0x000a }, + { 0x05, 0x01, -1, 0x03, 0x0062, 0x000c }, + { 0x05, 0x02, -1, 0x03, 0x0062, 0x000e }, + { 0x05, 0x02, -1, 0x03, 0x0062, 0x0012 }, + { 0x05, 0x03, -1, 0x03, 0x0062, 0x0016 }, + { 0x05, 0x03, -1, 0x03, 0x0062, 0x001e }, + { 0x05, 0x04, -1, 0x03, 0x0062, 0x0026 }, + { 0x05, 0x04, -1, 0x03, 0x0062, 0x0036 }, + { 0x00, 0x05, -1, 0x03, 0x0000, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0000, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0000, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0000, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0000, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0000, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0000, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0000, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0001, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0001, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0001, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0001, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0001, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0001, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0001, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0001, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0002, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0002, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0002, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0002, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0002, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0002, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0002, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0002, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0003, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0003, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0003, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0003, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0003, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0003, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0003, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0003, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0004, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0004, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0004, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0004, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0004, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0004, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0004, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0004, 0x0846 }, + { 0x00, 0x05, -1, 0x03, 0x0005, 0x0046 }, + { 0x00, 0x05, -1, 0x03, 0x0005, 0x0066 }, + { 0x00, 0x06, -1, 0x03, 0x0005, 0x0086 }, + { 0x00, 0x07, -1, 0x03, 0x0005, 0x00c6 }, + { 0x00, 0x08, -1, 0x03, 0x0005, 0x0146 }, + { 0x00, 0x09, -1, 0x03, 0x0005, 0x0246 }, + { 0x00, 0x0a, -1, 0x03, 0x0005, 0x0446 }, + { 0x00, 0x18, -1, 0x03, 0x0005, 0x0846 }, + { 0x01, 0x05, -1, 0x03, 0x0006, 0x0046 }, + { 0x01, 0x05, -1, 0x03, 0x0006, 0x0066 }, + { 0x01, 0x06, -1, 0x03, 0x0006, 0x0086 }, + { 0x01, 0x07, -1, 0x03, 0x0006, 0x00c6 }, + { 0x01, 0x08, -1, 0x03, 0x0006, 0x0146 }, + { 0x01, 0x09, -1, 0x03, 0x0006, 0x0246 }, + { 0x01, 0x0a, -1, 0x03, 0x0006, 0x0446 }, + { 0x01, 0x18, -1, 0x03, 0x0006, 0x0846 }, + { 0x01, 0x05, -1, 0x03, 0x0008, 0x0046 }, + { 0x01, 0x05, -1, 0x03, 0x0008, 0x0066 }, + { 0x01, 0x06, -1, 0x03, 0x0008, 0x0086 }, + { 0x01, 0x07, -1, 0x03, 0x0008, 0x00c6 }, + { 0x01, 0x08, -1, 0x03, 0x0008, 0x0146 }, + { 0x01, 0x09, -1, 0x03, 0x0008, 0x0246 }, + { 0x01, 0x0a, -1, 0x03, 0x0008, 0x0446 }, + { 0x01, 0x18, -1, 0x03, 0x0008, 0x0846 }, + { 0x06, 0x00, -1, 0x00, 0x0082, 0x0002 }, + { 0x06, 0x00, -1, 0x01, 0x0082, 0x0003 }, + { 0x06, 0x00, -1, 0x02, 0x0082, 0x0004 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0005 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0006 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0007 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0008 }, + { 0x06, 0x00, -1, 0x03, 0x0082, 0x0009 }, + { 0x07, 0x00, -1, 0x00, 0x00c2, 0x0002 }, + { 0x07, 0x00, -1, 0x01, 0x00c2, 0x0003 }, + { 0x07, 0x00, -1, 0x02, 0x00c2, 0x0004 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0005 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0006 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0007 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0008 }, + { 0x07, 0x00, -1, 0x03, 0x00c2, 0x0009 }, + { 0x08, 0x00, -1, 0x00, 0x0142, 0x0002 }, + { 0x08, 0x00, -1, 0x01, 0x0142, 0x0003 }, + { 0x08, 0x00, -1, 0x02, 0x0142, 0x0004 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0005 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0006 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0007 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0008 }, + { 0x08, 0x00, -1, 0x03, 0x0142, 0x0009 }, + { 0x09, 0x00, -1, 0x00, 0x0242, 0x0002 }, + { 0x09, 0x00, -1, 0x01, 0x0242, 0x0003 }, + { 0x09, 0x00, -1, 0x02, 0x0242, 0x0004 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0005 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0006 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0007 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0008 }, + { 0x09, 0x00, -1, 0x03, 0x0242, 0x0009 }, + { 0x0a, 0x00, -1, 0x00, 0x0442, 0x0002 }, + { 0x0a, 0x00, -1, 0x01, 0x0442, 0x0003 }, + { 0x0a, 0x00, -1, 0x02, 0x0442, 0x0004 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0005 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0006 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0007 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0008 }, + { 0x0a, 0x00, -1, 0x03, 0x0442, 0x0009 }, + { 0x0c, 0x00, -1, 0x00, 0x0842, 0x0002 }, + { 0x0c, 0x00, -1, 0x01, 0x0842, 0x0003 }, + { 0x0c, 0x00, -1, 0x02, 0x0842, 0x0004 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0005 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0006 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0007 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0008 }, + { 0x0c, 0x00, -1, 0x03, 0x0842, 0x0009 }, + { 0x0e, 0x00, -1, 0x00, 0x1842, 0x0002 }, + { 0x0e, 0x00, -1, 0x01, 0x1842, 0x0003 }, + { 0x0e, 0x00, -1, 0x02, 0x1842, 0x0004 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0005 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0006 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0007 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0008 }, + { 0x0e, 0x00, -1, 0x03, 0x1842, 0x0009 }, + { 0x18, 0x00, -1, 0x00, 0x5842, 0x0002 }, + { 0x18, 0x00, -1, 0x01, 0x5842, 0x0003 }, + { 0x18, 0x00, -1, 0x02, 0x5842, 0x0004 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0005 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0006 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0007 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0008 }, + { 0x18, 0x00, -1, 0x03, 0x5842, 0x0009 }, + { 0x02, 0x05, -1, 0x03, 0x000a, 0x0046 }, + { 0x02, 0x05, -1, 0x03, 0x000a, 0x0066 }, + { 0x02, 0x06, -1, 0x03, 0x000a, 0x0086 }, + { 0x02, 0x07, -1, 0x03, 0x000a, 0x00c6 }, + { 0x02, 0x08, -1, 0x03, 0x000a, 0x0146 }, + { 0x02, 0x09, -1, 0x03, 0x000a, 0x0246 }, + { 0x02, 0x0a, -1, 0x03, 0x000a, 0x0446 }, + { 0x02, 0x18, -1, 0x03, 0x000a, 0x0846 }, + { 0x02, 0x05, -1, 0x03, 0x000e, 0x0046 }, + { 0x02, 0x05, -1, 0x03, 0x000e, 0x0066 }, + { 0x02, 0x06, -1, 0x03, 0x000e, 0x0086 }, + { 0x02, 0x07, -1, 0x03, 0x000e, 0x00c6 }, + { 0x02, 0x08, -1, 0x03, 0x000e, 0x0146 }, + { 0x02, 0x09, -1, 0x03, 0x000e, 0x0246 }, + { 0x02, 0x0a, -1, 0x03, 0x000e, 0x0446 }, + { 0x02, 0x18, -1, 0x03, 0x000e, 0x0846 }, + { 0x03, 0x05, -1, 0x03, 0x0012, 0x0046 }, + { 0x03, 0x05, -1, 0x03, 0x0012, 0x0066 }, + { 0x03, 0x06, -1, 0x03, 0x0012, 0x0086 }, + { 0x03, 0x07, -1, 0x03, 0x0012, 0x00c6 }, + { 0x03, 0x08, -1, 0x03, 0x0012, 0x0146 }, + { 0x03, 0x09, -1, 0x03, 0x0012, 0x0246 }, + { 0x03, 0x0a, -1, 0x03, 0x0012, 0x0446 }, + { 0x03, 0x18, -1, 0x03, 0x0012, 0x0846 }, + { 0x03, 0x05, -1, 0x03, 0x001a, 0x0046 }, + { 0x03, 0x05, -1, 0x03, 0x001a, 0x0066 }, + { 0x03, 0x06, -1, 0x03, 0x001a, 0x0086 }, + { 0x03, 0x07, -1, 0x03, 0x001a, 0x00c6 }, + { 0x03, 0x08, -1, 0x03, 0x001a, 0x0146 }, + { 0x03, 0x09, -1, 0x03, 0x001a, 0x0246 }, + { 0x03, 0x0a, -1, 0x03, 0x001a, 0x0446 }, + { 0x03, 0x18, -1, 0x03, 0x001a, 0x0846 }, + { 0x04, 0x05, -1, 0x03, 0x0022, 0x0046 }, + { 0x04, 0x05, -1, 0x03, 0x0022, 0x0066 }, + { 0x04, 0x06, -1, 0x03, 0x0022, 0x0086 }, + { 0x04, 0x07, -1, 0x03, 0x0022, 0x00c6 }, + { 0x04, 0x08, -1, 0x03, 0x0022, 0x0146 }, + { 0x04, 0x09, -1, 0x03, 0x0022, 0x0246 }, + { 0x04, 0x0a, -1, 0x03, 0x0022, 0x0446 }, + { 0x04, 0x18, -1, 0x03, 0x0022, 0x0846 }, + { 0x04, 0x05, -1, 0x03, 0x0032, 0x0046 }, + { 0x04, 0x05, -1, 0x03, 0x0032, 0x0066 }, + { 0x04, 0x06, -1, 0x03, 0x0032, 0x0086 }, + { 0x04, 0x07, -1, 0x03, 0x0032, 0x00c6 }, + { 0x04, 0x08, -1, 0x03, 0x0032, 0x0146 }, + { 0x04, 0x09, -1, 0x03, 0x0032, 0x0246 }, + { 0x04, 0x0a, -1, 0x03, 0x0032, 0x0446 }, + { 0x04, 0x18, -1, 0x03, 0x0032, 0x0846 }, + { 0x05, 0x05, -1, 0x03, 0x0042, 0x0046 }, + { 0x05, 0x05, -1, 0x03, 0x0042, 0x0066 }, + { 0x05, 0x06, -1, 0x03, 0x0042, 0x0086 }, + { 0x05, 0x07, -1, 0x03, 0x0042, 0x00c6 }, + { 0x05, 0x08, -1, 0x03, 0x0042, 0x0146 }, + { 0x05, 0x09, -1, 0x03, 0x0042, 0x0246 }, + { 0x05, 0x0a, -1, 0x03, 0x0042, 0x0446 }, + { 0x05, 0x18, -1, 0x03, 0x0042, 0x0846 }, + { 0x05, 0x05, -1, 0x03, 0x0062, 0x0046 }, + { 0x05, 0x05, -1, 0x03, 0x0062, 0x0066 }, + { 0x05, 0x06, -1, 0x03, 0x0062, 0x0086 }, + { 0x05, 0x07, -1, 0x03, 0x0062, 0x00c6 }, + { 0x05, 0x08, -1, 0x03, 0x0062, 0x0146 }, + { 0x05, 0x09, -1, 0x03, 0x0062, 0x0246 }, + { 0x05, 0x0a, -1, 0x03, 0x0062, 0x0446 }, + { 0x05, 0x18, -1, 0x03, 0x0062, 0x0846 }, + { 0x06, 0x01, -1, 0x03, 0x0082, 0x000a }, + { 0x06, 0x01, -1, 0x03, 0x0082, 0x000c }, + { 0x06, 0x02, -1, 0x03, 0x0082, 0x000e }, + { 0x06, 0x02, -1, 0x03, 0x0082, 0x0012 }, + { 0x06, 0x03, -1, 0x03, 0x0082, 0x0016 }, + { 0x06, 0x03, -1, 0x03, 0x0082, 0x001e }, + { 0x06, 0x04, -1, 0x03, 0x0082, 0x0026 }, + { 0x06, 0x04, -1, 0x03, 0x0082, 0x0036 }, + { 0x07, 0x01, -1, 0x03, 0x00c2, 0x000a }, + { 0x07, 0x01, -1, 0x03, 0x00c2, 0x000c }, + { 0x07, 0x02, -1, 0x03, 0x00c2, 0x000e }, + { 0x07, 0x02, -1, 0x03, 0x00c2, 0x0012 }, + { 0x07, 0x03, -1, 0x03, 0x00c2, 0x0016 }, + { 0x07, 0x03, -1, 0x03, 0x00c2, 0x001e }, + { 0x07, 0x04, -1, 0x03, 0x00c2, 0x0026 }, + { 0x07, 0x04, -1, 0x03, 0x00c2, 0x0036 }, + { 0x08, 0x01, -1, 0x03, 0x0142, 0x000a }, + { 0x08, 0x01, -1, 0x03, 0x0142, 0x000c }, + { 0x08, 0x02, -1, 0x03, 0x0142, 0x000e }, + { 0x08, 0x02, -1, 0x03, 0x0142, 0x0012 }, + { 0x08, 0x03, -1, 0x03, 0x0142, 0x0016 }, + { 0x08, 0x03, -1, 0x03, 0x0142, 0x001e }, + { 0x08, 0x04, -1, 0x03, 0x0142, 0x0026 }, + { 0x08, 0x04, -1, 0x03, 0x0142, 0x0036 }, + { 0x09, 0x01, -1, 0x03, 0x0242, 0x000a }, + { 0x09, 0x01, -1, 0x03, 0x0242, 0x000c }, + { 0x09, 0x02, -1, 0x03, 0x0242, 0x000e }, + { 0x09, 0x02, -1, 0x03, 0x0242, 0x0012 }, + { 0x09, 0x03, -1, 0x03, 0x0242, 0x0016 }, + { 0x09, 0x03, -1, 0x03, 0x0242, 0x001e }, + { 0x09, 0x04, -1, 0x03, 0x0242, 0x0026 }, + { 0x09, 0x04, -1, 0x03, 0x0242, 0x0036 }, + { 0x0a, 0x01, -1, 0x03, 0x0442, 0x000a }, + { 0x0a, 0x01, -1, 0x03, 0x0442, 0x000c }, + { 0x0a, 0x02, -1, 0x03, 0x0442, 0x000e }, + { 0x0a, 0x02, -1, 0x03, 0x0442, 0x0012 }, + { 0x0a, 0x03, -1, 0x03, 0x0442, 0x0016 }, + { 0x0a, 0x03, -1, 0x03, 0x0442, 0x001e }, + { 0x0a, 0x04, -1, 0x03, 0x0442, 0x0026 }, + { 0x0a, 0x04, -1, 0x03, 0x0442, 0x0036 }, + { 0x0c, 0x01, -1, 0x03, 0x0842, 0x000a }, + { 0x0c, 0x01, -1, 0x03, 0x0842, 0x000c }, + { 0x0c, 0x02, -1, 0x03, 0x0842, 0x000e }, + { 0x0c, 0x02, -1, 0x03, 0x0842, 0x0012 }, + { 0x0c, 0x03, -1, 0x03, 0x0842, 0x0016 }, + { 0x0c, 0x03, -1, 0x03, 0x0842, 0x001e }, + { 0x0c, 0x04, -1, 0x03, 0x0842, 0x0026 }, + { 0x0c, 0x04, -1, 0x03, 0x0842, 0x0036 }, + { 0x0e, 0x01, -1, 0x03, 0x1842, 0x000a }, + { 0x0e, 0x01, -1, 0x03, 0x1842, 0x000c }, + { 0x0e, 0x02, -1, 0x03, 0x1842, 0x000e }, + { 0x0e, 0x02, -1, 0x03, 0x1842, 0x0012 }, + { 0x0e, 0x03, -1, 0x03, 0x1842, 0x0016 }, + { 0x0e, 0x03, -1, 0x03, 0x1842, 0x001e }, + { 0x0e, 0x04, -1, 0x03, 0x1842, 0x0026 }, + { 0x0e, 0x04, -1, 0x03, 0x1842, 0x0036 }, + { 0x18, 0x01, -1, 0x03, 0x5842, 0x000a }, + { 0x18, 0x01, -1, 0x03, 0x5842, 0x000c }, + { 0x18, 0x02, -1, 0x03, 0x5842, 0x000e }, + { 0x18, 0x02, -1, 0x03, 0x5842, 0x0012 }, + { 0x18, 0x03, -1, 0x03, 0x5842, 0x0016 }, + { 0x18, 0x03, -1, 0x03, 0x5842, 0x001e }, + { 0x18, 0x04, -1, 0x03, 0x5842, 0x0026 }, + { 0x18, 0x04, -1, 0x03, 0x5842, 0x0036 }, + { 0x06, 0x05, -1, 0x03, 0x0082, 0x0046 }, + { 0x06, 0x05, -1, 0x03, 0x0082, 0x0066 }, + { 0x06, 0x06, -1, 0x03, 0x0082, 0x0086 }, + { 0x06, 0x07, -1, 0x03, 0x0082, 0x00c6 }, + { 0x06, 0x08, -1, 0x03, 0x0082, 0x0146 }, + { 0x06, 0x09, -1, 0x03, 0x0082, 0x0246 }, + { 0x06, 0x0a, -1, 0x03, 0x0082, 0x0446 }, + { 0x06, 0x18, -1, 0x03, 0x0082, 0x0846 }, + { 0x07, 0x05, -1, 0x03, 0x00c2, 0x0046 }, + { 0x07, 0x05, -1, 0x03, 0x00c2, 0x0066 }, + { 0x07, 0x06, -1, 0x03, 0x00c2, 0x0086 }, + { 0x07, 0x07, -1, 0x03, 0x00c2, 0x00c6 }, + { 0x07, 0x08, -1, 0x03, 0x00c2, 0x0146 }, + { 0x07, 0x09, -1, 0x03, 0x00c2, 0x0246 }, + { 0x07, 0x0a, -1, 0x03, 0x00c2, 0x0446 }, + { 0x07, 0x18, -1, 0x03, 0x00c2, 0x0846 }, + { 0x08, 0x05, -1, 0x03, 0x0142, 0x0046 }, + { 0x08, 0x05, -1, 0x03, 0x0142, 0x0066 }, + { 0x08, 0x06, -1, 0x03, 0x0142, 0x0086 }, + { 0x08, 0x07, -1, 0x03, 0x0142, 0x00c6 }, + { 0x08, 0x08, -1, 0x03, 0x0142, 0x0146 }, + { 0x08, 0x09, -1, 0x03, 0x0142, 0x0246 }, + { 0x08, 0x0a, -1, 0x03, 0x0142, 0x0446 }, + { 0x08, 0x18, -1, 0x03, 0x0142, 0x0846 }, + { 0x09, 0x05, -1, 0x03, 0x0242, 0x0046 }, + { 0x09, 0x05, -1, 0x03, 0x0242, 0x0066 }, + { 0x09, 0x06, -1, 0x03, 0x0242, 0x0086 }, + { 0x09, 0x07, -1, 0x03, 0x0242, 0x00c6 }, + { 0x09, 0x08, -1, 0x03, 0x0242, 0x0146 }, + { 0x09, 0x09, -1, 0x03, 0x0242, 0x0246 }, + { 0x09, 0x0a, -1, 0x03, 0x0242, 0x0446 }, + { 0x09, 0x18, -1, 0x03, 0x0242, 0x0846 }, + { 0x0a, 0x05, -1, 0x03, 0x0442, 0x0046 }, + { 0x0a, 0x05, -1, 0x03, 0x0442, 0x0066 }, + { 0x0a, 0x06, -1, 0x03, 0x0442, 0x0086 }, + { 0x0a, 0x07, -1, 0x03, 0x0442, 0x00c6 }, + { 0x0a, 0x08, -1, 0x03, 0x0442, 0x0146 }, + { 0x0a, 0x09, -1, 0x03, 0x0442, 0x0246 }, + { 0x0a, 0x0a, -1, 0x03, 0x0442, 0x0446 }, + { 0x0a, 0x18, -1, 0x03, 0x0442, 0x0846 }, + { 0x0c, 0x05, -1, 0x03, 0x0842, 0x0046 }, + { 0x0c, 0x05, -1, 0x03, 0x0842, 0x0066 }, + { 0x0c, 0x06, -1, 0x03, 0x0842, 0x0086 }, + { 0x0c, 0x07, -1, 0x03, 0x0842, 0x00c6 }, + { 0x0c, 0x08, -1, 0x03, 0x0842, 0x0146 }, + { 0x0c, 0x09, -1, 0x03, 0x0842, 0x0246 }, + { 0x0c, 0x0a, -1, 0x03, 0x0842, 0x0446 }, + { 0x0c, 0x18, -1, 0x03, 0x0842, 0x0846 }, + { 0x0e, 0x05, -1, 0x03, 0x1842, 0x0046 }, + { 0x0e, 0x05, -1, 0x03, 0x1842, 0x0066 }, + { 0x0e, 0x06, -1, 0x03, 0x1842, 0x0086 }, + { 0x0e, 0x07, -1, 0x03, 0x1842, 0x00c6 }, + { 0x0e, 0x08, -1, 0x03, 0x1842, 0x0146 }, + { 0x0e, 0x09, -1, 0x03, 0x1842, 0x0246 }, + { 0x0e, 0x0a, -1, 0x03, 0x1842, 0x0446 }, + { 0x0e, 0x18, -1, 0x03, 0x1842, 0x0846 }, + { 0x18, 0x05, -1, 0x03, 0x5842, 0x0046 }, + { 0x18, 0x05, -1, 0x03, 0x5842, 0x0066 }, + { 0x18, 0x06, -1, 0x03, 0x5842, 0x0086 }, + { 0x18, 0x07, -1, 0x03, 0x5842, 0x00c6 }, + { 0x18, 0x08, -1, 0x03, 0x5842, 0x0146 }, + { 0x18, 0x09, -1, 0x03, 0x5842, 0x0246 }, + { 0x18, 0x0a, -1, 0x03, 0x5842, 0x0446 }, + { 0x18, 0x18, -1, 0x03, 0x5842, 0x0846 }, +}; diff --git a/packages/runtime/vendor/brotli/c/dec/state.c b/packages/runtime/vendor/brotli/c/dec/state.c new file mode 100644 index 000000000..dcf61b9eb --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/state.c @@ -0,0 +1,186 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "state.h" + +#include "../common/dictionary.h" +#include "../common/platform.h" +#include "huffman.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#ifdef BROTLI_REPORTING +/* When BROTLI_REPORTING is defined extra reporting module have to be linked. */ +void BrotliDecoderOnStart(const BrotliDecoderState* s); +void BrotliDecoderOnFinish(const BrotliDecoderState* s); +#define BROTLI_DECODER_ON_START(s) BrotliDecoderOnStart(s); +#define BROTLI_DECODER_ON_FINISH(s) BrotliDecoderOnFinish(s); +#else +#if !defined(BROTLI_DECODER_ON_START) +#define BROTLI_DECODER_ON_START(s) (void)(s); +#endif +#if !defined(BROTLI_DECODER_ON_FINISH) +#define BROTLI_DECODER_ON_FINISH(s) (void)(s); +#endif +#endif + +BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s, + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + BROTLI_DECODER_ON_START(s); + if (!alloc_func) { + s->alloc_func = BrotliDefaultAllocFunc; + s->free_func = BrotliDefaultFreeFunc; + s->memory_manager_opaque = 0; + } else { + s->alloc_func = alloc_func; + s->free_func = free_func; + s->memory_manager_opaque = opaque; + } + + s->error_code = 0; /* BROTLI_DECODER_NO_ERROR */ + + BrotliInitBitReader(&s->br); + s->state = BROTLI_STATE_UNINITED; + s->large_window = 0; + s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE; + s->substate_uncompressed = BROTLI_STATE_UNCOMPRESSED_NONE; + s->substate_decode_uint8 = BROTLI_STATE_DECODE_UINT8_NONE; + s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_NONE; + + s->buffer_length = 0; + s->loop_counter = 0; + s->pos = 0; + s->rb_roundtrips = 0; + s->partial_pos_out = 0; + s->used_input = 0; + + s->block_type_trees = NULL; + s->block_len_trees = NULL; + s->ringbuffer = NULL; + s->ringbuffer_size = 0; + s->new_ringbuffer_size = 0; + s->ringbuffer_mask = 0; + + s->context_map = NULL; + s->context_modes = NULL; + s->dist_context_map = NULL; + s->context_map_slice = NULL; + s->dist_context_map_slice = NULL; + + s->literal_hgroup.codes = NULL; + s->literal_hgroup.htrees = NULL; + s->insert_copy_hgroup.codes = NULL; + s->insert_copy_hgroup.htrees = NULL; + s->distance_hgroup.codes = NULL; + s->distance_hgroup.htrees = NULL; + + s->is_last_metablock = 0; + s->is_uncompressed = 0; + s->is_metadata = 0; + s->should_wrap_ringbuffer = 0; + s->canny_ringbuffer_allocation = 1; + + s->window_bits = 0; + s->max_distance = 0; + s->dist_rb[0] = 16; + s->dist_rb[1] = 15; + s->dist_rb[2] = 11; + s->dist_rb[3] = 4; + s->dist_rb_idx = 0; + s->block_type_trees = NULL; + s->block_len_trees = NULL; + + s->mtf_upper_bound = 63; + + s->compound_dictionary = NULL; + s->dictionary = + BrotliSharedDictionaryCreateInstance(alloc_func, free_func, opaque); + if (!s->dictionary) return BROTLI_FALSE; + + s->metadata_start_func = NULL; + s->metadata_chunk_func = NULL; + s->metadata_callback_opaque = 0; + + return BROTLI_TRUE; +} + +void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) { + s->meta_block_remaining_len = 0; + s->block_length[0] = BROTLI_BLOCK_SIZE_CAP; + s->block_length[1] = BROTLI_BLOCK_SIZE_CAP; + s->block_length[2] = BROTLI_BLOCK_SIZE_CAP; + s->num_block_types[0] = 1; + s->num_block_types[1] = 1; + s->num_block_types[2] = 1; + s->block_type_rb[0] = 1; + s->block_type_rb[1] = 0; + s->block_type_rb[2] = 1; + s->block_type_rb[3] = 0; + s->block_type_rb[4] = 1; + s->block_type_rb[5] = 0; + s->context_map = NULL; + s->context_modes = NULL; + s->dist_context_map = NULL; + s->context_map_slice = NULL; + s->literal_htree = NULL; + s->dist_context_map_slice = NULL; + s->dist_htree_index = 0; + s->context_lookup = NULL; + s->literal_hgroup.codes = NULL; + s->literal_hgroup.htrees = NULL; + s->insert_copy_hgroup.codes = NULL; + s->insert_copy_hgroup.htrees = NULL; + s->distance_hgroup.codes = NULL; + s->distance_hgroup.htrees = NULL; +} + +void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) { + BROTLI_DECODER_FREE(s, s->context_modes); + BROTLI_DECODER_FREE(s, s->context_map); + BROTLI_DECODER_FREE(s, s->dist_context_map); + BROTLI_DECODER_FREE(s, s->literal_hgroup.htrees); + BROTLI_DECODER_FREE(s, s->insert_copy_hgroup.htrees); + BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees); +} + +void BrotliDecoderStateCleanup(BrotliDecoderState* s) { + BrotliDecoderStateCleanupAfterMetablock(s); + + BROTLI_DECODER_ON_FINISH(s); + + BROTLI_DECODER_FREE(s, s->compound_dictionary); + BrotliSharedDictionaryDestroyInstance(s->dictionary); + s->dictionary = NULL; + BROTLI_DECODER_FREE(s, s->ringbuffer); + BROTLI_DECODER_FREE(s, s->block_type_trees); +} + +BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s, + HuffmanTreeGroup* group, brotli_reg_t alphabet_size_max, + brotli_reg_t alphabet_size_limit, brotli_reg_t ntrees) { + /* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables) + This number is discovered "unlimited" "enough" calculator; it is actually + a wee bigger than required in several cases (especially for alphabets with + less than 16 symbols). */ + const size_t max_table_size = alphabet_size_limit + 376; + const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size; + const size_t htree_size = sizeof(HuffmanCode*) * ntrees; + /* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */ + HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s, + code_size + htree_size); + group->alphabet_size_max = (uint16_t)alphabet_size_max; + group->alphabet_size_limit = (uint16_t)alphabet_size_limit; + group->num_htrees = (uint16_t)ntrees; + group->htrees = p; + group->codes = p ? (HuffmanCode*)(&p[ntrees]) : NULL; + return !!p; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/dec/state.h b/packages/runtime/vendor/brotli/c/dec/state.h new file mode 100644 index 000000000..aa371fba2 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/state.h @@ -0,0 +1,396 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Brotli state for partial streaming decoding. */ + +#ifndef BROTLI_DEC_STATE_H_ +#define BROTLI_DEC_STATE_H_ + +#include "../common/constants.h" +#include "../common/platform.h" +#include +#include +#include "bit_reader.h" +#include "huffman.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Graphviz diagram that describes state transitions: + +digraph States { + graph [compound=true] + concentrate=true + node [shape="box"] + + UNINITED -> {LARGE_WINDOW_BITS -> INITIALIZE} + subgraph cluster_metablock_workflow { + style="rounded" + label=< METABLOCK CYCLE > + METABLOCK_BEGIN -> METABLOCK_HEADER + METABLOCK_HEADER:sw -> METADATA + METABLOCK_HEADER:s -> UNCOMPRESSED + METABLOCK_HEADER:se -> METABLOCK_DONE:ne + METADATA:s -> METABLOCK_DONE:w + UNCOMPRESSED:s -> METABLOCK_DONE:n + METABLOCK_DONE:e -> METABLOCK_BEGIN:e [constraint="false"] + } + INITIALIZE -> METABLOCK_BEGIN + METABLOCK_DONE -> DONE + + subgraph cluster_compressed_metablock { + style="rounded" + label=< COMPRESSED METABLOCK > + + subgraph cluster_command { + style="rounded" + label=< HOT LOOP > + + _METABLOCK_DONE_PORT_ [shape=point style=invis] + + { + // Set different shape for nodes returning from "compressed metablock". + node [shape=invhouse]; CMD_INNER CMD_POST_DECODE_LITERALS; + CMD_POST_WRAP_COPY; CMD_INNER_WRITE; CMD_POST_WRITE_1; + } + + CMD_BEGIN -> CMD_INNER -> CMD_POST_DECODE_LITERALS -> CMD_POST_WRAP_COPY + + // IO ("write") nodes are not in the hot loop! + CMD_INNER_WRITE [style=dashed] + CMD_INNER -> CMD_INNER_WRITE + CMD_POST_WRITE_1 [style=dashed] + CMD_POST_DECODE_LITERALS -> CMD_POST_WRITE_1 + CMD_POST_WRITE_2 [style=dashed] + CMD_POST_WRAP_COPY -> CMD_POST_WRITE_2 + + CMD_POST_WRITE_1 -> CMD_BEGIN:s [constraint="false"] + CMD_INNER_WRITE -> {CMD_INNER CMD_POST_DECODE_LITERALS} + [constraint="false"] + CMD_BEGIN:ne -> CMD_POST_DECODE_LITERALS [constraint="false"] + CMD_POST_WRAP_COPY -> CMD_BEGIN [constraint="false"] + CMD_POST_DECODE_LITERALS -> CMD_BEGIN:ne [constraint="false"] + CMD_POST_WRITE_2 -> CMD_POST_WRAP_COPY [constraint="false"] + {rank=same; CMD_BEGIN; CMD_INNER; CMD_POST_DECODE_LITERALS; + CMD_POST_WRAP_COPY} + {rank=same; CMD_INNER_WRITE; CMD_POST_WRITE_1; CMD_POST_WRITE_2} + + {CMD_INNER CMD_POST_DECODE_LITERALS CMD_POST_WRAP_COPY} -> + _METABLOCK_DONE_PORT_ [style=invis] + {CMD_INNER_WRITE CMD_POST_WRITE_1} -> _METABLOCK_DONE_PORT_ + [constraint="false" style=invis] + } + + BEFORE_COMPRESSED_METABLOCK_HEADER:s -> HUFFMAN_CODE_0:n + HUFFMAN_CODE_0 -> HUFFMAN_CODE_1 -> HUFFMAN_CODE_2 -> HUFFMAN_CODE_3 + HUFFMAN_CODE_0 -> METABLOCK_HEADER_2 -> CONTEXT_MODES -> CONTEXT_MAP_1 + CONTEXT_MAP_1 -> CONTEXT_MAP_2 -> TREE_GROUP + TREE_GROUP -> BEFORE_COMPRESSED_METABLOCK_BODY:e + BEFORE_COMPRESSED_METABLOCK_BODY:s -> CMD_BEGIN:n + + HUFFMAN_CODE_3:e -> HUFFMAN_CODE_0:ne [constraint="false"] + {rank=same; HUFFMAN_CODE_0; HUFFMAN_CODE_1; HUFFMAN_CODE_2; HUFFMAN_CODE_3} + {rank=same; METABLOCK_HEADER_2; CONTEXT_MODES; CONTEXT_MAP_1; CONTEXT_MAP_2; + TREE_GROUP} + } + METABLOCK_HEADER:e -> BEFORE_COMPRESSED_METABLOCK_HEADER:n + + _METABLOCK_DONE_PORT_ -> METABLOCK_DONE:se + [constraint="false" ltail=cluster_command] + + UNINITED [shape=Mdiamond]; + DONE [shape=Msquare]; +} + + + */ + +typedef enum { + BROTLI_STATE_UNINITED, + BROTLI_STATE_LARGE_WINDOW_BITS, + BROTLI_STATE_INITIALIZE, + BROTLI_STATE_METABLOCK_BEGIN, + BROTLI_STATE_METABLOCK_HEADER, + BROTLI_STATE_METABLOCK_HEADER_2, + BROTLI_STATE_CONTEXT_MODES, + BROTLI_STATE_COMMAND_BEGIN, + BROTLI_STATE_COMMAND_INNER, + BROTLI_STATE_COMMAND_POST_DECODE_LITERALS, + BROTLI_STATE_COMMAND_POST_WRAP_COPY, + BROTLI_STATE_UNCOMPRESSED, + BROTLI_STATE_METADATA, + BROTLI_STATE_COMMAND_INNER_WRITE, + BROTLI_STATE_METABLOCK_DONE, + BROTLI_STATE_COMMAND_POST_WRITE_1, + BROTLI_STATE_COMMAND_POST_WRITE_2, + BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_HEADER, + BROTLI_STATE_HUFFMAN_CODE_0, + BROTLI_STATE_HUFFMAN_CODE_1, + BROTLI_STATE_HUFFMAN_CODE_2, + BROTLI_STATE_HUFFMAN_CODE_3, + BROTLI_STATE_CONTEXT_MAP_1, + BROTLI_STATE_CONTEXT_MAP_2, + BROTLI_STATE_TREE_GROUP, + BROTLI_STATE_BEFORE_COMPRESSED_METABLOCK_BODY, + BROTLI_STATE_DONE +} BrotliRunningState; + +typedef enum { + BROTLI_STATE_METABLOCK_HEADER_NONE, + BROTLI_STATE_METABLOCK_HEADER_EMPTY, + BROTLI_STATE_METABLOCK_HEADER_NIBBLES, + BROTLI_STATE_METABLOCK_HEADER_SIZE, + BROTLI_STATE_METABLOCK_HEADER_UNCOMPRESSED, + BROTLI_STATE_METABLOCK_HEADER_RESERVED, + BROTLI_STATE_METABLOCK_HEADER_BYTES, + BROTLI_STATE_METABLOCK_HEADER_METADATA +} BrotliRunningMetablockHeaderState; + +typedef enum { + BROTLI_STATE_UNCOMPRESSED_NONE, + BROTLI_STATE_UNCOMPRESSED_WRITE +} BrotliRunningUncompressedState; + +typedef enum { + BROTLI_STATE_TREE_GROUP_NONE, + BROTLI_STATE_TREE_GROUP_LOOP +} BrotliRunningTreeGroupState; + +typedef enum { + BROTLI_STATE_CONTEXT_MAP_NONE, + BROTLI_STATE_CONTEXT_MAP_READ_PREFIX, + BROTLI_STATE_CONTEXT_MAP_HUFFMAN, + BROTLI_STATE_CONTEXT_MAP_DECODE, + BROTLI_STATE_CONTEXT_MAP_TRANSFORM +} BrotliRunningContextMapState; + +typedef enum { + BROTLI_STATE_HUFFMAN_NONE, + BROTLI_STATE_HUFFMAN_SIMPLE_SIZE, + BROTLI_STATE_HUFFMAN_SIMPLE_READ, + BROTLI_STATE_HUFFMAN_SIMPLE_BUILD, + BROTLI_STATE_HUFFMAN_COMPLEX, + BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS +} BrotliRunningHuffmanState; + +typedef enum { + BROTLI_STATE_DECODE_UINT8_NONE, + BROTLI_STATE_DECODE_UINT8_SHORT, + BROTLI_STATE_DECODE_UINT8_LONG +} BrotliRunningDecodeUint8State; + +typedef enum { + BROTLI_STATE_READ_BLOCK_LENGTH_NONE, + BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX +} BrotliRunningReadBlockLengthState; + +/* BrotliDecoderState addon, used for Compound Dictionary functionality. */ +typedef struct BrotliDecoderCompoundDictionary { + int num_chunks; + int total_size; + int br_index; + int br_offset; + int br_length; + int br_copied; + const uint8_t* chunks[16]; + int chunk_offsets[16]; + int block_bits; + uint8_t block_map[256]; +} BrotliDecoderCompoundDictionary; + +typedef struct BrotliMetablockHeaderArena { + BrotliRunningTreeGroupState substate_tree_group; + BrotliRunningContextMapState substate_context_map; + BrotliRunningHuffmanState substate_huffman; + + brotli_reg_t sub_loop_counter; + + brotli_reg_t repeat_code_len; + brotli_reg_t prev_code_len; + + /* For ReadHuffmanCode. */ + brotli_reg_t symbol; + brotli_reg_t repeat; + brotli_reg_t space; + + /* Huffman table for "histograms". */ + HuffmanCode table[32]; + /* List of heads of symbol chains. */ + uint16_t* symbol_lists; + /* Storage from symbol_lists. */ + uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 + + BROTLI_NUM_COMMAND_SYMBOLS]; + /* Tails of symbol chains. */ + int next_symbol[32]; + uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES]; + /* Population counts for the code lengths. */ + uint16_t code_length_histo[16]; + /* TODO(eustas): +2 bytes padding */ + + /* For HuffmanTreeGroupDecode. */ + int htree_index; + HuffmanCode* next; + + /* For DecodeContextMap. */ + brotli_reg_t context_index; + brotli_reg_t max_run_length_prefix; + brotli_reg_t code; + HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272]; +} BrotliMetablockHeaderArena; + +typedef struct BrotliMetablockBodyArena { + uint8_t dist_extra_bits[544]; + brotli_reg_t dist_offset[544]; +} BrotliMetablockBodyArena; + +struct BrotliDecoderStateStruct { + BrotliRunningState state; + + /* This counter is reused for several disjoint loops. */ + int loop_counter; + + BrotliBitReader br; + + brotli_alloc_func alloc_func; + brotli_free_func free_func; + void* memory_manager_opaque; + + /* Temporary storage for remaining input. Brotli stream format is designed in + a way, that 64 bits are enough to make progress in decoding. */ + union { + uint64_t u64; + uint8_t u8[8]; + } buffer; + brotli_reg_t buffer_length; + + int pos; + int max_backward_distance; + int max_distance; + int ringbuffer_size; + int ringbuffer_mask; + int dist_rb_idx; + int dist_rb[4]; + int error_code; + int meta_block_remaining_len; + + uint8_t* ringbuffer; + uint8_t* ringbuffer_end; + HuffmanCode* htree_command; + const uint8_t* context_lookup; + uint8_t* context_map_slice; + uint8_t* dist_context_map_slice; + + /* This ring buffer holds a few past copy distances that will be used by + some special distance codes. */ + HuffmanTreeGroup literal_hgroup; + HuffmanTreeGroup insert_copy_hgroup; + HuffmanTreeGroup distance_hgroup; + HuffmanCode* block_type_trees; + HuffmanCode* block_len_trees; + /* This is true if the literal context map histogram type always matches the + block type. It is then not needed to keep the context (faster decoding). */ + int trivial_literal_context; + /* Distance context is actual after command is decoded and before distance is + computed. After distance computation it is used as a temporary variable. */ + int distance_context; + brotli_reg_t block_length[3]; + brotli_reg_t block_length_index; + brotli_reg_t num_block_types[3]; + brotli_reg_t block_type_rb[6]; + brotli_reg_t distance_postfix_bits; + brotli_reg_t num_direct_distance_codes; + brotli_reg_t num_dist_htrees; + uint8_t* dist_context_map; + HuffmanCode* literal_htree; + + /* For partial write operations. */ + size_t rb_roundtrips; /* how many times we went around the ring-buffer */ + size_t partial_pos_out; /* how much output to the user in total */ + + /* For InverseMoveToFrontTransform. */ + brotli_reg_t mtf_upper_bound; + uint32_t mtf[64 + 1]; + + int copy_length; + int distance_code; + + uint8_t dist_htree_index; + /* TODO(eustas): +3 bytes padding */ + + /* Less used attributes are at the end of this struct. */ + + brotli_decoder_metadata_start_func metadata_start_func; + brotli_decoder_metadata_chunk_func metadata_chunk_func; + void* metadata_callback_opaque; + + /* For reporting. */ + uint64_t used_input; /* how many bytes of input are consumed */ + + /* States inside function calls. */ + BrotliRunningMetablockHeaderState substate_metablock_header; + BrotliRunningUncompressedState substate_uncompressed; + BrotliRunningDecodeUint8State substate_decode_uint8; + BrotliRunningReadBlockLengthState substate_read_block_length; + + int new_ringbuffer_size; + /* TODO(eustas): +4 bytes padding */ + + unsigned int is_last_metablock : 1; + unsigned int is_uncompressed : 1; + unsigned int is_metadata : 1; + unsigned int should_wrap_ringbuffer : 1; + unsigned int canny_ringbuffer_allocation : 1; + unsigned int large_window : 1; + unsigned int window_bits : 6; + unsigned int size_nibbles : 8; + /* TODO(eustas): +12 bits padding */ + + brotli_reg_t num_literal_htrees; + uint8_t* context_map; + uint8_t* context_modes; + + BrotliSharedDictionary* dictionary; + BrotliDecoderCompoundDictionary* compound_dictionary; + + uint32_t trivial_literal_contexts[8]; /* 256 bits */ + + union { + BrotliMetablockHeaderArena header; + BrotliMetablockBodyArena body; + } arena; +}; + +typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal; +#define BrotliDecoderState BrotliDecoderStateInternal + +BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s, + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); +BROTLI_INTERNAL void BrotliDecoderStateCleanup(BrotliDecoderState* s); +BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s); +BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock( + BrotliDecoderState* s); +BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit( + BrotliDecoderState* s, HuffmanTreeGroup* group, + brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit, + brotli_reg_t ntrees); + +#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L) + +#define BROTLI_DECODER_FREE(S, X) { \ + S->free_func(S->memory_manager_opaque, X); \ + X = NULL; \ +} + +/* Literal/Command/Distance block size maximum; same as maximum metablock size; + used as block size when there is no block switching. */ +#define BROTLI_BLOCK_SIZE_CAP (1U << 24) + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_STATE_H_ */ diff --git a/packages/runtime/vendor/brotli/c/dec/static_init.c b/packages/runtime/vendor/brotli/c/dec/static_init.c new file mode 100644 index 000000000..1345052c5 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/static_init.c @@ -0,0 +1,53 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "static_init.h" + +#include "../common/platform.h" +#include "../common/static_init.h" + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +#include "../common/dictionary.h" +#include "prefix.h" +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +static BROTLI_BOOL DoBrotliDecoderStaticInit(void) { + BROTLI_BOOL ok = BrotliDecoderInitCmdLut(kCmdLut); + if (!ok) return BROTLI_FALSE; + return BROTLI_TRUE; +} +#endif /* BROTLI_STATIC_INIT_NONE */ + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) +static BROTLI_BOOL kEarlyInitOk; +static __attribute__((constructor)) void BrotliDecoderStaticInitEarly(void) { + kEarlyInitOk = DoBrotliDecoderStaticInit(); +} +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_LAZY) +static BROTLI_BOOL kLazyInitOk; +void BrotliDecoderLazyStaticInitInner(void) { + kLazyInitOk = DoBrotliDecoderStaticInit(); +} +#endif /* BROTLI_STATIC_INIT_EARLY */ + +BROTLI_BOOL BrotliDecoderEnsureStaticInit(void) { +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_NONE) + return BROTLI_TRUE; +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) + return kEarlyInitOk; +#else + return kLazyInitOk; +#endif +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/dec/static_init.h b/packages/runtime/vendor/brotli/c/dec/static_init.h new file mode 100644 index 000000000..4ae063ef5 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/dec/static_init.h @@ -0,0 +1,30 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Central point for static initialization. */ + +#ifndef THIRD_PARTY_BROTLI_DEC_STATIC_INIT_H_ +#define THIRD_PARTY_BROTLI_DEC_STATIC_INIT_H_ + +#include "../common/platform.h" +#include "../common/static_init.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_LAZY) +BROTLI_INTERNAL void BrotliDecoderLazyStaticInitInner(void); +BROTLI_INTERNAL void BrotliDecoderLazyStaticInit(void); +#endif /* BROTLI_STATIC_INIT */ + +BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderEnsureStaticInit(void); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif // THIRD_PARTY_BROTLI_DEC_STATIC_INIT_H_ diff --git a/packages/runtime/vendor/brotli/c/enc/backward_references.c b/packages/runtime/vendor/brotli/c/enc/backward_references.c new file mode 100644 index 000000000..5d1c0ed63 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/backward_references.c @@ -0,0 +1,231 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function to find backward reference copies. */ + +#include "backward_references.h" + +#include "../common/constants.h" +#include "../common/context.h" +#include "../common/platform.h" +#include "command.h" +#include "compound_dictionary.h" +#include "encoder_dict.h" +#include "hash.h" +#include "params.h" +#include "quality.h" /* IWYU pragma: keep for inc */ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static BROTLI_INLINE size_t ComputeDistanceCode(size_t distance, + size_t max_distance, + const int* dist_cache) { + if (distance <= max_distance) { + size_t distance_plus_3 = distance + 3; + size_t offset0 = distance_plus_3 - (size_t)dist_cache[0]; + size_t offset1 = distance_plus_3 - (size_t)dist_cache[1]; + if (distance == (size_t)dist_cache[0]) { + return 0; + } else if (distance == (size_t)dist_cache[1]) { + return 1; + } else if (offset0 < 7) { + return (0x9750468 >> (4 * offset0)) & 0xF; + } else if (offset1 < 7) { + return (0xFDB1ACE >> (4 * offset1)) & 0xF; + } else if (distance == (size_t)dist_cache[2]) { + return 2; + } else if (distance == (size_t)dist_cache[3]) { + return 3; + } + } + return distance + BROTLI_NUM_DISTANCE_SHORT_CODES - 1; +} + +#define EXPAND_CAT(a, b) CAT(a, b) +#define CAT(a, b) a ## b +#define FN(X) EXPAND_CAT(X, HASHER()) +#define EXPORT_FN(X) EXPAND_CAT(X, EXPAND_CAT(PREFIX(), HASHER())) + +#define PREFIX() N +#define ENABLE_COMPOUND_DICTIONARY 0 + +#define HASHER() H2 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H3 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H4 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H5 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H6 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H40 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H41 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H42 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H54 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H35 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H55 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H65 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#if defined(BROTLI_MAX_SIMD_QUALITY) +#define HASHER() H58 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER + +#define HASHER() H68 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#endif + +#undef ENABLE_COMPOUND_DICTIONARY +#undef PREFIX +#define PREFIX() D +#define ENABLE_COMPOUND_DICTIONARY 1 + +#define HASHER() H5 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#define HASHER() H6 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#define HASHER() H40 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#define HASHER() H41 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#define HASHER() H42 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#define HASHER() H55 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#define HASHER() H65 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#if defined(BROTLI_MAX_SIMD_QUALITY) +#define HASHER() H58 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#define HASHER() H68 +/* NOLINTNEXTLINE(build/include) */ +#include "backward_references_inc.h" +#undef HASHER +#endif + +#undef ENABLE_COMPOUND_DICTIONARY +#undef PREFIX + +#undef EXPORT_FN +#undef FN +#undef CAT +#undef EXPAND_CAT + +void BrotliCreateBackwardReferences(size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals) { + if (params->dictionary.compound.num_chunks != 0) { + switch (params->hasher.type) { +#define CASE_(N) \ + case N: \ + CreateBackwardReferencesDH ## N(num_bytes, \ + position, ringbuffer, ringbuffer_mask, \ + literal_context_lut, params, hasher, dist_cache, \ + last_insert_len, commands, num_commands, num_literals); \ + return; + CASE_(5) + CASE_(6) +#if defined(BROTLI_MAX_SIMD_QUALITY) + CASE_(58) + CASE_(68) +#endif + CASE_(40) + CASE_(41) + CASE_(42) + CASE_(55) + CASE_(65) +#undef CASE_ + default: + BROTLI_DCHECK(BROTLI_FALSE); + break; + } + } + + switch (params->hasher.type) { +#define CASE_(N) \ + case N: \ + CreateBackwardReferencesNH ## N(num_bytes, \ + position, ringbuffer, ringbuffer_mask, \ + literal_context_lut, params, hasher, dist_cache, \ + last_insert_len, commands, num_commands, num_literals); \ + return; + FOR_GENERIC_HASHERS(CASE_) +#undef CASE_ + default: + BROTLI_DCHECK(BROTLI_FALSE); + break; + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/backward_references.h b/packages/runtime/vendor/brotli/c/enc/backward_references.h new file mode 100644 index 000000000..17f0c8495 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/backward_references.h @@ -0,0 +1,36 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function to find backward reference copies. */ + +#ifndef BROTLI_ENC_BACKWARD_REFERENCES_H_ +#define BROTLI_ENC_BACKWARD_REFERENCES_H_ + +#include "../common/context.h" +#include "../common/platform.h" +#include "command.h" +#include "hash.h" +#include "params.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* "commands" points to the next output command to write to, "*num_commands" is + initially the total amount of commands output by previous + CreateBackwardReferences calls, and must be incremented by the amount written + by this call. */ +BROTLI_INTERNAL void BrotliCreateBackwardReferences(size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_BACKWARD_REFERENCES_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/backward_references_hq.c b/packages/runtime/vendor/brotli/c/enc/backward_references_hq.c new file mode 100644 index 000000000..ab8b12187 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/backward_references_hq.c @@ -0,0 +1,939 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function to find backward reference copies. */ + +#include "backward_references_hq.h" + +#include "../common/constants.h" +#include "../common/context.h" +#include "../common/platform.h" +#include "command.h" +#include "compound_dictionary.h" +#include "encoder_dict.h" +#include "fast_log.h" +#include "find_match_length.h" +#include "hash.h" +#include "literal_cost.h" +#include "memory.h" +#include "params.h" +#include "prefix.h" +#include "quality.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* BrotliCalculateDistanceCodeLimit(BROTLI_MAX_ALLOWED_DISTANCE, 3, 120). */ +#define BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE 544 + +static const float kInfinity = 1.7e38f; /* ~= 2 ^ 127 */ + +static const BROTLI_MODEL("small") uint32_t kDistanceCacheIndex[] = { + 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, +}; +static const BROTLI_MODEL("small") int kDistanceCacheOffset[] = { + 0, 0, 0, 0, -1, 1, -2, 2, -3, 3, -1, 1, -2, 2, -3, 3 +}; + +void BrotliInitZopfliNodes(ZopfliNode* array, size_t length) { + ZopfliNode stub; + size_t i; + stub.length = 1; + stub.distance = 0; + stub.dcode_insert_length = 0; + stub.u.cost = kInfinity; + for (i = 0; i < length; ++i) array[i] = stub; +} + +static BROTLI_INLINE uint32_t ZopfliNodeCopyLength(const ZopfliNode* self) { + return self->length & 0x1FFFFFF; +} + +static BROTLI_INLINE uint32_t ZopfliNodeLengthCode(const ZopfliNode* self) { + const uint32_t modifier = self->length >> 25; + return ZopfliNodeCopyLength(self) + 9u - modifier; +} + +static BROTLI_INLINE uint32_t ZopfliNodeCopyDistance(const ZopfliNode* self) { + return self->distance; +} + +static BROTLI_INLINE uint32_t ZopfliNodeDistanceCode(const ZopfliNode* self) { + const uint32_t short_code = self->dcode_insert_length >> 27; + return short_code == 0 ? + ZopfliNodeCopyDistance(self) + BROTLI_NUM_DISTANCE_SHORT_CODES - 1 : + short_code - 1; +} + +static BROTLI_INLINE uint32_t ZopfliNodeCommandLength(const ZopfliNode* self) { + return ZopfliNodeCopyLength(self) + (self->dcode_insert_length & 0x7FFFFFF); +} + +/* Temporary data for ZopfliCostModelSetFromCommands. */ +typedef struct ZopfliCostModelArena { + uint32_t histogram_literal[BROTLI_NUM_LITERAL_SYMBOLS]; + uint32_t histogram_cmd[BROTLI_NUM_COMMAND_SYMBOLS]; + uint32_t histogram_dist[BROTLI_MAX_EFFECTIVE_DISTANCE_ALPHABET_SIZE]; + float cost_literal[BROTLI_NUM_LITERAL_SYMBOLS]; +} ZopfliCostModelArena; + +/* Histogram based cost model for zopflification. */ +typedef struct ZopfliCostModel { + /* The insert and copy length symbols. */ + float cost_cmd_[BROTLI_NUM_COMMAND_SYMBOLS]; + float* cost_dist_; + uint32_t distance_histogram_size; + /* Cumulative costs of literals per position in the stream. */ + float* literal_costs_; + float min_cost_cmd_; + size_t num_bytes_; + + /* Temporary data. */ + union { + size_t literal_histograms[3 * 256]; + ZopfliCostModelArena arena; + }; +} ZopfliCostModel; + +static void InitZopfliCostModel( + MemoryManager* m, ZopfliCostModel* self, const BrotliDistanceParams* dist, + size_t num_bytes) { + self->num_bytes_ = num_bytes; + self->literal_costs_ = BROTLI_ALLOC(m, float, num_bytes + 2); + self->cost_dist_ = BROTLI_ALLOC(m, float, dist->alphabet_size_limit); + self->distance_histogram_size = dist->alphabet_size_limit; + if (BROTLI_IS_OOM(m)) return; +} + +static void CleanupZopfliCostModel(MemoryManager* m, ZopfliCostModel* self) { + BROTLI_FREE(m, self->literal_costs_); + BROTLI_FREE(m, self->cost_dist_); +} + +static void SetCost(const uint32_t* histogram, size_t histogram_size, + BROTLI_BOOL literal_histogram, float* cost) { + size_t sum = 0; + size_t missing_symbol_sum; + float log2sum; + float missing_symbol_cost; + size_t i; + for (i = 0; i < histogram_size; i++) { + sum += histogram[i]; + } + log2sum = (float)FastLog2(sum); + missing_symbol_sum = sum; + if (!literal_histogram) { + for (i = 0; i < histogram_size; i++) { + if (histogram[i] == 0) missing_symbol_sum++; + } + } + missing_symbol_cost = (float)FastLog2(missing_symbol_sum) + 2; + for (i = 0; i < histogram_size; i++) { + if (histogram[i] == 0) { + cost[i] = missing_symbol_cost; + continue; + } + + /* Shannon bits for this symbol. */ + cost[i] = log2sum - (float)FastLog2(histogram[i]); + + /* Cannot be coded with less than 1 bit */ + if (cost[i] < 1) cost[i] = 1; + } +} + +static void ZopfliCostModelSetFromCommands(ZopfliCostModel* self, + size_t position, + const uint8_t* ringbuffer, + size_t ringbuffer_mask, + const Command* commands, + size_t num_commands, + size_t last_insert_len) { + ZopfliCostModelArena* arena = &self->arena; + size_t pos = position - last_insert_len; + float min_cost_cmd = kInfinity; + size_t i; + float* cost_cmd = self->cost_cmd_; + + memset(arena->histogram_literal, 0, sizeof(arena->histogram_literal)); + memset(arena->histogram_cmd, 0, sizeof(arena->histogram_cmd)); + memset(arena->histogram_dist, 0, sizeof(arena->histogram_dist)); + + for (i = 0; i < num_commands; i++) { + size_t inslength = commands[i].insert_len_; + size_t copylength = CommandCopyLen(&commands[i]); + size_t distcode = commands[i].dist_prefix_ & 0x3FF; + size_t cmdcode = commands[i].cmd_prefix_; + size_t j; + + arena->histogram_cmd[cmdcode]++; + if (cmdcode >= 128) arena->histogram_dist[distcode]++; + + for (j = 0; j < inslength; j++) { + arena->histogram_literal[ringbuffer[(pos + j) & ringbuffer_mask]]++; + } + + pos += inslength + copylength; + } + + SetCost(arena->histogram_literal, BROTLI_NUM_LITERAL_SYMBOLS, BROTLI_TRUE, + arena->cost_literal); + SetCost(arena->histogram_cmd, BROTLI_NUM_COMMAND_SYMBOLS, BROTLI_FALSE, + cost_cmd); + SetCost(arena->histogram_dist, self->distance_histogram_size, BROTLI_FALSE, + self->cost_dist_); + + for (i = 0; i < BROTLI_NUM_COMMAND_SYMBOLS; ++i) { + min_cost_cmd = BROTLI_MIN(float, min_cost_cmd, cost_cmd[i]); + } + self->min_cost_cmd_ = min_cost_cmd; + + { + float* literal_costs = self->literal_costs_; + float literal_carry = 0.0; + size_t num_bytes = self->num_bytes_; + literal_costs[0] = 0.0; + for (i = 0; i < num_bytes; ++i) { + literal_carry += + arena->cost_literal[ringbuffer[(position + i) & ringbuffer_mask]]; + literal_costs[i + 1] = literal_costs[i] + literal_carry; + literal_carry -= literal_costs[i + 1] - literal_costs[i]; + } + } +} + +static void ZopfliCostModelSetFromLiteralCosts(ZopfliCostModel* self, + size_t position, + const uint8_t* ringbuffer, + size_t ringbuffer_mask) { + float* literal_costs = self->literal_costs_; + float literal_carry = 0.0; + float* cost_dist = self->cost_dist_; + float* cost_cmd = self->cost_cmd_; + size_t num_bytes = self->num_bytes_; + size_t i; + BrotliEstimateBitCostsForLiterals(position, num_bytes, ringbuffer_mask, + ringbuffer, self->literal_histograms, + &literal_costs[1]); + literal_costs[0] = 0.0; + for (i = 0; i < num_bytes; ++i) { + literal_carry += literal_costs[i + 1]; + literal_costs[i + 1] = literal_costs[i] + literal_carry; + literal_carry -= literal_costs[i + 1] - literal_costs[i]; + } + for (i = 0; i < BROTLI_NUM_COMMAND_SYMBOLS; ++i) { + cost_cmd[i] = (float)FastLog2(11 + (uint32_t)i); + } + for (i = 0; i < self->distance_histogram_size; ++i) { + cost_dist[i] = (float)FastLog2(20 + (uint32_t)i); + } + self->min_cost_cmd_ = (float)FastLog2(11); +} + +static BROTLI_INLINE float ZopfliCostModelGetCommandCost( + const ZopfliCostModel* self, uint16_t cmdcode) { + return self->cost_cmd_[cmdcode]; +} + +static BROTLI_INLINE float ZopfliCostModelGetDistanceCost( + const ZopfliCostModel* self, size_t distcode) { + return self->cost_dist_[distcode]; +} + +static BROTLI_INLINE float ZopfliCostModelGetLiteralCosts( + const ZopfliCostModel* self, size_t from, size_t to) { + return self->literal_costs_[to] - self->literal_costs_[from]; +} + +static BROTLI_INLINE float ZopfliCostModelGetMinCostCmd( + const ZopfliCostModel* self) { + return self->min_cost_cmd_; +} + +/* REQUIRES: len >= 2, start_pos <= pos */ +/* REQUIRES: cost < kInfinity, nodes[start_pos].cost < kInfinity */ +/* Maintains the "ZopfliNode array invariant". */ +static BROTLI_INLINE void UpdateZopfliNode(ZopfliNode* nodes, size_t pos, + size_t start_pos, size_t len, size_t len_code, size_t dist, + size_t short_code, float cost) { + ZopfliNode* next = &nodes[pos + len]; + next->length = (uint32_t)(len | ((len + 9u - len_code) << 25)); + next->distance = (uint32_t)dist; + next->dcode_insert_length = (uint32_t)( + (short_code << 27) | (pos - start_pos)); + next->u.cost = cost; +} + +typedef struct PosData { + size_t pos; + int distance_cache[4]; + float costdiff; + float cost; +} PosData; + +/* Maintains the smallest 8 cost difference together with their positions */ +typedef struct StartPosQueue { + PosData q_[8]; + size_t idx_; +} StartPosQueue; + +static BROTLI_INLINE void InitStartPosQueue(StartPosQueue* self) { + self->idx_ = 0; +} + +static size_t StartPosQueueSize(const StartPosQueue* self) { + return BROTLI_MIN(size_t, self->idx_, 8); +} + +static void StartPosQueuePush(StartPosQueue* self, const PosData* posdata) { + size_t offset = ~(self->idx_++) & 7; + size_t len = StartPosQueueSize(self); + size_t i; + PosData* q = self->q_; + q[offset] = *posdata; + /* Restore the sorted order. In the list of |len| items at most |len - 1| + adjacent element comparisons / swaps are required. */ + for (i = 1; i < len; ++i) { + if (q[offset & 7].costdiff > q[(offset + 1) & 7].costdiff) { + BROTLI_SWAP(PosData, q, offset & 7, (offset + 1) & 7); + } + ++offset; + } +} + +static const PosData* StartPosQueueAt(const StartPosQueue* self, size_t k) { + return &self->q_[(k - self->idx_) & 7]; +} + +/* Returns the minimum possible copy length that can improve the cost of any */ +/* future position. */ +static size_t ComputeMinimumCopyLength(const float start_cost, + const ZopfliNode* nodes, + const size_t num_bytes, + const size_t pos) { + /* Compute the minimum possible cost of reaching any future position. */ + float min_cost = start_cost; + size_t len = 2; + size_t next_len_bucket = 4; + size_t next_len_offset = 10; + while (pos + len <= num_bytes && nodes[pos + len].u.cost <= min_cost) { + /* We already reached (pos + len) with no more cost than the minimum + possible cost of reaching anything from this pos, so there is no point in + looking for lengths <= len. */ + ++len; + if (len == next_len_offset) { + /* We reached the next copy length code bucket, so we add one more + extra bit to the minimum cost. */ + min_cost += 1.0f; + next_len_offset += next_len_bucket; + next_len_bucket *= 2; + } + } + return len; +} + +/* REQUIRES: nodes[pos].cost < kInfinity + REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */ +static uint32_t ComputeDistanceShortcut(const size_t block_start, + const size_t pos, + const size_t max_backward_limit, + const size_t gap, + const ZopfliNode* nodes) { + const size_t c_len = ZopfliNodeCopyLength(&nodes[pos]); + const size_t i_len = nodes[pos].dcode_insert_length & 0x7FFFFFF; + const size_t dist = ZopfliNodeCopyDistance(&nodes[pos]); + /* Since |block_start + pos| is the end position of the command, the copy part + starts from |block_start + pos - c_len|. Distances that are greater than + this or greater than |max_backward_limit| + |gap| are static dictionary + references, and do not update the last distances. + Also distance code 0 (last distance) does not update the last distances. */ + if (pos == 0) { + return 0; + } else if (dist + c_len <= block_start + pos + gap && + dist <= max_backward_limit + gap && + ZopfliNodeDistanceCode(&nodes[pos]) > 0) { + return (uint32_t)pos; + } else { + return nodes[pos - c_len - i_len].u.shortcut; + } +} + +/* Fills in dist_cache[0..3] with the last four distances (as defined by + Section 4. of the Spec) that would be used at (block_start + pos) if we + used the shortest path of commands from block_start, computed from + nodes[0..pos]. The last four distances at block_start are in + starting_dist_cache[0..3]. + REQUIRES: nodes[pos].cost < kInfinity + REQUIRES: nodes[0..pos] satisfies that "ZopfliNode array invariant". */ +static void ComputeDistanceCache(const size_t pos, + const int* starting_dist_cache, + const ZopfliNode* nodes, + int* dist_cache) { + int idx = 0; + size_t p = nodes[pos].u.shortcut; + while (idx < 4 && p > 0) { + const size_t i_len = nodes[p].dcode_insert_length & 0x7FFFFFF; + const size_t c_len = ZopfliNodeCopyLength(&nodes[p]); + const size_t dist = ZopfliNodeCopyDistance(&nodes[p]); + dist_cache[idx++] = (int)dist; + /* Because of prerequisite, p >= c_len + i_len >= 2. */ + p = nodes[p - c_len - i_len].u.shortcut; + } + for (; idx < 4; ++idx) { + dist_cache[idx] = *starting_dist_cache++; + } +} + +/* Maintains "ZopfliNode array invariant" and pushes node to the queue, if it + is eligible. */ +static void EvaluateNode( + const size_t block_start, const size_t pos, const size_t max_backward_limit, + const size_t gap, const int* starting_dist_cache, + const ZopfliCostModel* model, StartPosQueue* queue, ZopfliNode* nodes) { + /* Save cost, because ComputeDistanceCache invalidates it. */ + float node_cost = nodes[pos].u.cost; + nodes[pos].u.shortcut = ComputeDistanceShortcut( + block_start, pos, max_backward_limit, gap, nodes); + if (node_cost <= ZopfliCostModelGetLiteralCosts(model, 0, pos)) { + PosData posdata; + posdata.pos = pos; + posdata.cost = node_cost; + posdata.costdiff = node_cost - + ZopfliCostModelGetLiteralCosts(model, 0, pos); + ComputeDistanceCache( + pos, starting_dist_cache, nodes, posdata.distance_cache); + StartPosQueuePush(queue, &posdata); + } +} + +/* Returns longest copy length. */ +static size_t UpdateNodes( + const size_t num_bytes, const size_t block_start, const size_t pos, + const uint8_t* ringbuffer, const size_t ringbuffer_mask, + const BrotliEncoderParams* params, const size_t max_backward_limit, + const int* starting_dist_cache, const size_t num_matches, + const BackwardMatch* matches, const ZopfliCostModel* model, + StartPosQueue* queue, ZopfliNode* nodes) { + const size_t stream_offset = params->stream_offset; + const size_t cur_ix = block_start + pos; + const size_t cur_ix_masked = cur_ix & ringbuffer_mask; + const size_t max_distance = BROTLI_MIN(size_t, cur_ix, max_backward_limit); + const size_t dictionary_start = BROTLI_MIN(size_t, + cur_ix + stream_offset, max_backward_limit); + const size_t max_len = num_bytes - pos; + const size_t max_zopfli_len = MaxZopfliLen(params); + const size_t max_iters = MaxZopfliCandidates(params); + size_t min_len; + size_t result = 0; + size_t k; + const CompoundDictionary* addon = ¶ms->dictionary.compound; + size_t gap = addon->total_size; + + BROTLI_DCHECK(cur_ix_masked + max_len <= ringbuffer_mask); + + EvaluateNode(block_start + stream_offset, pos, max_backward_limit, gap, + starting_dist_cache, model, queue, nodes); + + { + const PosData* posdata = StartPosQueueAt(queue, 0); + float min_cost = (posdata->cost + ZopfliCostModelGetMinCostCmd(model) + + ZopfliCostModelGetLiteralCosts(model, posdata->pos, pos)); + min_len = ComputeMinimumCopyLength(min_cost, nodes, num_bytes, pos); + } + + /* Go over the command starting positions in order of increasing cost + difference. */ + for (k = 0; k < max_iters && k < StartPosQueueSize(queue); ++k) { + const PosData* posdata = StartPosQueueAt(queue, k); + const size_t start = posdata->pos; + const uint16_t inscode = GetInsertLengthCode(pos - start); + const float start_costdiff = posdata->costdiff; + const float base_cost = start_costdiff + (float)GetInsertExtra(inscode) + + ZopfliCostModelGetLiteralCosts(model, 0, pos); + + /* Look for last distance matches using the distance cache from this + starting position. */ + size_t best_len = min_len - 1; + size_t j = 0; + for (; j < BROTLI_NUM_DISTANCE_SHORT_CODES && best_len < max_len; ++j) { + const size_t idx = kDistanceCacheIndex[j]; + const size_t backward = + (size_t)(posdata->distance_cache[idx] + kDistanceCacheOffset[j]); + size_t prev_ix = cur_ix - backward; + size_t len = 0; + uint8_t continuation = ringbuffer[cur_ix_masked + best_len]; + if (cur_ix_masked + best_len > ringbuffer_mask) { + break; + } + if (BROTLI_PREDICT_FALSE(backward > dictionary_start + gap)) { + /* Word dictionary -> ignore. */ + continue; + } + if (backward <= max_distance) { + /* Regular backward reference. */ + if (prev_ix >= cur_ix) { + continue; + } + + prev_ix &= ringbuffer_mask; + if (prev_ix + best_len > ringbuffer_mask || + continuation != ringbuffer[prev_ix + best_len]) { + continue; + } + len = FindMatchLengthWithLimit(&ringbuffer[prev_ix], + &ringbuffer[cur_ix_masked], + max_len); + } else if (backward > dictionary_start) { + size_t d = 0; + size_t offset; + size_t limit; + const uint8_t* source; + offset = dictionary_start + 1 + addon->total_size - 1; + while (offset >= backward + addon->chunk_offsets[d + 1]) d++; + source = addon->chunk_source[d]; + offset = offset - addon->chunk_offsets[d] - backward; + limit = addon->chunk_offsets[d + 1] - addon->chunk_offsets[d] - offset; + limit = limit > max_len ? max_len : limit; + if (best_len >= limit || + continuation != source[offset + best_len]) { + continue; + } + len = FindMatchLengthWithLimit(&source[offset], + &ringbuffer[cur_ix_masked], + limit); + } else { + /* "Gray" area. It is addressable by decoder, but this encoder + instance does not have that data -> should not touch it. */ + continue; + } + { + const float dist_cost = base_cost + + ZopfliCostModelGetDistanceCost(model, j); + size_t l; + for (l = best_len + 1; l <= len; ++l) { + const uint16_t copycode = GetCopyLengthCode(l); + const uint16_t cmdcode = + CombineLengthCodes(inscode, copycode, j == 0); + const float cost = (cmdcode < 128 ? base_cost : dist_cost) + + (float)GetCopyExtra(copycode) + + ZopfliCostModelGetCommandCost(model, cmdcode); + if (cost < nodes[pos + l].u.cost) { + UpdateZopfliNode(nodes, pos, start, l, l, backward, j + 1, cost); + result = BROTLI_MAX(size_t, result, l); + } + best_len = l; + } + } + } + + /* At higher iterations look only for new last distance matches, since + looking only for new command start positions with the same distances + does not help much. */ + if (k >= 2) continue; + + { + /* Loop through all possible copy lengths at this position. */ + size_t len = min_len; + for (j = 0; j < num_matches; ++j) { + BackwardMatch match = matches[j]; + size_t dist = match.distance; + BROTLI_BOOL is_dictionary_match = + TO_BROTLI_BOOL(dist > dictionary_start + gap); + /* We already tried all possible last distance matches, so we can use + normal distance code here. */ + size_t dist_code = dist + BROTLI_NUM_DISTANCE_SHORT_CODES - 1; + uint16_t dist_symbol; + uint32_t distextra; + uint32_t distnumextra; + float dist_cost; + size_t max_match_len; + PrefixEncodeCopyDistance( + dist_code, params->dist.num_direct_distance_codes, + params->dist.distance_postfix_bits, &dist_symbol, &distextra); + distnumextra = dist_symbol >> 10; + dist_cost = base_cost + (float)distnumextra + + ZopfliCostModelGetDistanceCost(model, dist_symbol & 0x3FF); + + /* Try all copy lengths up until the maximum copy length corresponding + to this distance. If the distance refers to the static dictionary, or + the maximum length is long enough, try only one maximum length. */ + max_match_len = BackwardMatchLength(&match); + if (len < max_match_len && + (is_dictionary_match || max_match_len > max_zopfli_len)) { + len = max_match_len; + } + for (; len <= max_match_len; ++len) { + const size_t len_code = + is_dictionary_match ? BackwardMatchLengthCode(&match) : len; + const uint16_t copycode = GetCopyLengthCode(len_code); + const uint16_t cmdcode = CombineLengthCodes(inscode, copycode, 0); + const float cost = dist_cost + (float)GetCopyExtra(copycode) + + ZopfliCostModelGetCommandCost(model, cmdcode); + if (cost < nodes[pos + len].u.cost) { + UpdateZopfliNode(nodes, pos, start, len, len_code, dist, 0, cost); + result = BROTLI_MAX(size_t, result, len); + } + } + } + } + } + return result; +} + +static size_t ComputeShortestPathFromNodes(size_t num_bytes, + ZopfliNode* nodes) { + size_t index = num_bytes; + size_t num_commands = 0; + while ((nodes[index].dcode_insert_length & 0x7FFFFFF) == 0 && + nodes[index].length == 1) --index; + nodes[index].u.next = BROTLI_UINT32_MAX; + while (index != 0) { + size_t len = ZopfliNodeCommandLength(&nodes[index]); + index -= len; + nodes[index].u.next = (uint32_t)len; + num_commands++; + } + return num_commands; +} + +/* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */ +void BrotliZopfliCreateCommands(const size_t num_bytes, + const size_t block_start, const ZopfliNode* nodes, int* dist_cache, + size_t* last_insert_len, const BrotliEncoderParams* params, + Command* commands, size_t* num_literals) { + const size_t stream_offset = params->stream_offset; + const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); + size_t pos = 0; + uint32_t offset = nodes[0].u.next; + size_t i; + size_t gap = params->dictionary.compound.total_size; + for (i = 0; offset != BROTLI_UINT32_MAX; i++) { + const ZopfliNode* next = &nodes[pos + offset]; + size_t copy_length = ZopfliNodeCopyLength(next); + size_t insert_length = next->dcode_insert_length & 0x7FFFFFF; + pos += insert_length; + offset = next->u.next; + if (i == 0) { + insert_length += *last_insert_len; + *last_insert_len = 0; + } + { + size_t distance = ZopfliNodeCopyDistance(next); + size_t len_code = ZopfliNodeLengthCode(next); + size_t dictionary_start = BROTLI_MIN(size_t, + block_start + pos + stream_offset, max_backward_limit); + BROTLI_BOOL is_dictionary = + TO_BROTLI_BOOL(distance > dictionary_start + gap); + size_t dist_code = ZopfliNodeDistanceCode(next); + InitCommand(&commands[i], ¶ms->dist, insert_length, + copy_length, (int)len_code - (int)copy_length, dist_code); + + if (!is_dictionary && dist_code > 0) { + dist_cache[3] = dist_cache[2]; + dist_cache[2] = dist_cache[1]; + dist_cache[1] = dist_cache[0]; + dist_cache[0] = (int)distance; + } + } + + *num_literals += insert_length; + pos += copy_length; + } + *last_insert_len += num_bytes - pos; +} + +static size_t ZopfliIterate(size_t num_bytes, size_t position, + const uint8_t* ringbuffer, size_t ringbuffer_mask, + const BrotliEncoderParams* params, const size_t gap, const int* dist_cache, + const ZopfliCostModel* model, const uint32_t* num_matches, + const BackwardMatch* matches, ZopfliNode* nodes) { + const size_t stream_offset = params->stream_offset; + const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); + const size_t max_zopfli_len = MaxZopfliLen(params); + StartPosQueue queue; + size_t cur_match_pos = 0; + size_t i; + nodes[0].length = 0; + nodes[0].u.cost = 0; + InitStartPosQueue(&queue); + for (i = 0; i + 3 < num_bytes; i++) { + size_t skip = UpdateNodes(num_bytes, position, i, ringbuffer, + ringbuffer_mask, params, max_backward_limit, dist_cache, + num_matches[i], &matches[cur_match_pos], model, &queue, nodes); + if (skip < BROTLI_LONG_COPY_QUICK_STEP) skip = 0; + cur_match_pos += num_matches[i]; + if (num_matches[i] == 1 && + BackwardMatchLength(&matches[cur_match_pos - 1]) > max_zopfli_len) { + skip = BROTLI_MAX(size_t, + BackwardMatchLength(&matches[cur_match_pos - 1]), skip); + } + if (skip > 1) { + skip--; + while (skip) { + i++; + if (i + 3 >= num_bytes) break; + EvaluateNode(position + stream_offset, i, max_backward_limit, gap, + dist_cache, model, &queue, nodes); + cur_match_pos += num_matches[i]; + skip--; + } + } + } + return ComputeShortestPathFromNodes(num_bytes, nodes); +} + +static void MergeMatches(BackwardMatch* dst, + BackwardMatch* src1, size_t len1, BackwardMatch* src2, size_t len2) { + while (len1 > 0 && len2 > 0) { + size_t l1 = BackwardMatchLength(src1); + size_t l2 = BackwardMatchLength(src2); + if (l1 < l2 || ((l1 == l2) && (src1->distance < src2->distance))) { + *dst++ = *src1++; + len1--; + } else { + *dst++ = *src2++; + len2--; + } + } + while (len1-- > 0) *dst++ = *src1++; + while (len2-- > 0) *dst++ = *src2++; +} + +/* REQUIRES: nodes != NULL and len(nodes) >= num_bytes + 1 */ +size_t BrotliZopfliComputeShortestPath(MemoryManager* m, size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + const int* dist_cache, Hasher* hasher, ZopfliNode* nodes) { + const size_t stream_offset = params->stream_offset; + const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); + const size_t max_zopfli_len = MaxZopfliLen(params); + StartPosQueue queue; + BackwardMatch* BROTLI_RESTRICT matches = + BROTLI_ALLOC(m, BackwardMatch, 2 * (MAX_NUM_MATCHES_H10 + 64)); + const size_t store_end = num_bytes >= StoreLookaheadH10() ? + position + num_bytes - StoreLookaheadH10() + 1 : position; + size_t i; + const CompoundDictionary* addon = ¶ms->dictionary.compound; + size_t gap = addon->total_size; + size_t lz_matches_offset = + (addon->num_chunks != 0) ? (MAX_NUM_MATCHES_H10 + 128) : 0; + ZopfliCostModel* model = BROTLI_ALLOC(m, ZopfliCostModel, 1); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(model) || BROTLI_IS_NULL(matches)) { + return 0; + } + nodes[0].length = 0; + nodes[0].u.cost = 0; + InitZopfliCostModel(m, model, ¶ms->dist, num_bytes); + if (BROTLI_IS_OOM(m)) return 0; + ZopfliCostModelSetFromLiteralCosts( + model, position, ringbuffer, ringbuffer_mask); + InitStartPosQueue(&queue); + for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; i++) { + const size_t pos = position + i; + const size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit); + const size_t dictionary_start = BROTLI_MIN(size_t, + pos + stream_offset, max_backward_limit); + size_t skip; + size_t num_matches; + int dict_id = 0; + if (params->dictionary.contextual.context_based) { + uint8_t p1 = pos >= 1 ? + ringbuffer[(size_t)(pos - 1) & ringbuffer_mask] : 0; + uint8_t p2 = pos >= 2 ? + ringbuffer[(size_t)(pos - 2) & ringbuffer_mask] : 0; + dict_id = params->dictionary.contextual.context_map[ + BROTLI_CONTEXT(p1, p2, literal_context_lut)]; + } + num_matches = FindAllMatchesH10(&hasher->privat._H10, + params->dictionary.contextual.dict[dict_id], + ringbuffer, ringbuffer_mask, pos, num_bytes - i, max_distance, + dictionary_start + gap, params, &matches[lz_matches_offset]); + if (addon->num_chunks != 0) { + size_t cd_matches = LookupAllCompoundDictionaryMatches(addon, + ringbuffer, ringbuffer_mask, pos, 3, num_bytes - i, + dictionary_start, params->dist.max_distance, + &matches[lz_matches_offset - 64], 64); + MergeMatches(matches, &matches[lz_matches_offset - 64], cd_matches, + &matches[lz_matches_offset], num_matches); + num_matches += cd_matches; + } + if (num_matches > 0 && + BackwardMatchLength(&matches[num_matches - 1]) > max_zopfli_len) { + matches[0] = matches[num_matches - 1]; + num_matches = 1; + } + skip = UpdateNodes(num_bytes, position, i, ringbuffer, ringbuffer_mask, + params, max_backward_limit, dist_cache, num_matches, matches, model, + &queue, nodes); + if (skip < BROTLI_LONG_COPY_QUICK_STEP) skip = 0; + if (num_matches == 1 && BackwardMatchLength(&matches[0]) > max_zopfli_len) { + skip = BROTLI_MAX(size_t, BackwardMatchLength(&matches[0]), skip); + } + if (skip > 1) { + /* Add the tail of the copy to the hasher. */ + StoreRangeH10(&hasher->privat._H10, + ringbuffer, ringbuffer_mask, pos + 1, BROTLI_MIN( + size_t, pos + skip, store_end)); + skip--; + while (skip) { + i++; + if (i + HashTypeLengthH10() - 1 >= num_bytes) break; + EvaluateNode(position + stream_offset, i, max_backward_limit, gap, + dist_cache, model, &queue, nodes); + skip--; + } + } + } + CleanupZopfliCostModel(m, model); + BROTLI_FREE(m, model); + BROTLI_FREE(m, matches); + return ComputeShortestPathFromNodes(num_bytes, nodes); +} + +void BrotliCreateZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals) { + ZopfliNode* nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(nodes)) return; + BrotliInitZopfliNodes(nodes, num_bytes + 1); + *num_commands += BrotliZopfliComputeShortestPath(m, num_bytes, + position, ringbuffer, ringbuffer_mask, literal_context_lut, params, + dist_cache, hasher, nodes); + if (BROTLI_IS_OOM(m)) return; + BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache, + last_insert_len, params, commands, num_literals); + BROTLI_FREE(m, nodes); +} + +void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals) { + const size_t stream_offset = params->stream_offset; + const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); + uint32_t* num_matches = BROTLI_ALLOC(m, uint32_t, num_bytes); + size_t matches_size = 4 * num_bytes; + const size_t store_end = num_bytes >= StoreLookaheadH10() ? + position + num_bytes - StoreLookaheadH10() + 1 : position; + size_t cur_match_pos = 0; + size_t i; + size_t orig_num_literals; + size_t orig_last_insert_len; + int orig_dist_cache[4]; + size_t orig_num_commands; + ZopfliCostModel* model = BROTLI_ALLOC(m, ZopfliCostModel, 1); + ZopfliNode* nodes; + BackwardMatch* matches = BROTLI_ALLOC(m, BackwardMatch, matches_size); + const CompoundDictionary* addon = ¶ms->dictionary.compound; + size_t gap = addon->total_size; + size_t shadow_matches = + (addon->num_chunks != 0) ? (MAX_NUM_MATCHES_H10 + 128) : 0; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(model) || + BROTLI_IS_NULL(num_matches) || BROTLI_IS_NULL(matches)) { + return; + } + for (i = 0; i + HashTypeLengthH10() - 1 < num_bytes; ++i) { + const size_t pos = position + i; + size_t max_distance = BROTLI_MIN(size_t, pos, max_backward_limit); + size_t dictionary_start = BROTLI_MIN(size_t, + pos + stream_offset, max_backward_limit); + size_t max_length = num_bytes - i; + size_t num_found_matches; + size_t cur_match_end; + size_t j; + int dict_id = 0; + if (params->dictionary.contextual.context_based) { + uint8_t p1 = pos >= 1 ? + ringbuffer[(size_t)(pos - 1) & ringbuffer_mask] : 0; + uint8_t p2 = pos >= 2 ? + ringbuffer[(size_t)(pos - 2) & ringbuffer_mask] : 0; + dict_id = params->dictionary.contextual.context_map[ + BROTLI_CONTEXT(p1, p2, literal_context_lut)]; + } + /* Ensure that we have enough free slots. */ + BROTLI_ENSURE_CAPACITY(m, BackwardMatch, matches, matches_size, + cur_match_pos + MAX_NUM_MATCHES_H10 + shadow_matches); + if (BROTLI_IS_OOM(m)) return; + num_found_matches = FindAllMatchesH10(&hasher->privat._H10, + params->dictionary.contextual.dict[dict_id], + ringbuffer, ringbuffer_mask, pos, max_length, + max_distance, dictionary_start + gap, params, + &matches[cur_match_pos + shadow_matches]); + if (addon->num_chunks != 0) { + size_t cd_matches = LookupAllCompoundDictionaryMatches(addon, + ringbuffer, ringbuffer_mask, pos, 3, max_length, + dictionary_start, params->dist.max_distance, + &matches[cur_match_pos + shadow_matches - 64], 64); + MergeMatches(&matches[cur_match_pos], + &matches[cur_match_pos + shadow_matches - 64], cd_matches, + &matches[cur_match_pos + shadow_matches], num_found_matches); + num_found_matches += cd_matches; + } + cur_match_end = cur_match_pos + num_found_matches; + for (j = cur_match_pos; j + 1 < cur_match_end; ++j) { + BROTLI_DCHECK(BackwardMatchLength(&matches[j]) <= + BackwardMatchLength(&matches[j + 1])); + } + num_matches[i] = (uint32_t)num_found_matches; + if (num_found_matches > 0) { + const size_t match_len = BackwardMatchLength(&matches[cur_match_end - 1]); + if (match_len > MAX_ZOPFLI_LEN_QUALITY_11) { + const size_t skip = match_len - 1; + matches[cur_match_pos++] = matches[cur_match_end - 1]; + num_matches[i] = 1; + /* Add the tail of the copy to the hasher. */ + StoreRangeH10(&hasher->privat._H10, + ringbuffer, ringbuffer_mask, pos + 1, + BROTLI_MIN(size_t, pos + match_len, store_end)); + memset(&num_matches[i + 1], 0, skip * sizeof(num_matches[0])); + i += skip; + } else { + cur_match_pos = cur_match_end; + } + } + } + orig_num_literals = *num_literals; + orig_last_insert_len = *last_insert_len; + memcpy(orig_dist_cache, dist_cache, 4 * sizeof(dist_cache[0])); + orig_num_commands = *num_commands; + nodes = BROTLI_ALLOC(m, ZopfliNode, num_bytes + 1); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(nodes)) return; + InitZopfliCostModel(m, model, ¶ms->dist, num_bytes); + if (BROTLI_IS_OOM(m)) return; + for (i = 0; i < 2; i++) { + BrotliInitZopfliNodes(nodes, num_bytes + 1); + if (i == 0) { + ZopfliCostModelSetFromLiteralCosts( + model, position, ringbuffer, ringbuffer_mask); + } else { + ZopfliCostModelSetFromCommands(model, position, ringbuffer, + ringbuffer_mask, commands, *num_commands - orig_num_commands, + orig_last_insert_len); + } + *num_commands = orig_num_commands; + *num_literals = orig_num_literals; + *last_insert_len = orig_last_insert_len; + memcpy(dist_cache, orig_dist_cache, 4 * sizeof(dist_cache[0])); + *num_commands += ZopfliIterate(num_bytes, position, ringbuffer, + ringbuffer_mask, params, gap, dist_cache, model, num_matches, matches, + nodes); + BrotliZopfliCreateCommands(num_bytes, position, nodes, dist_cache, + last_insert_len, params, commands, num_literals); + } + CleanupZopfliCostModel(m, model); + BROTLI_FREE(m, model); + BROTLI_FREE(m, nodes); + BROTLI_FREE(m, matches); + BROTLI_FREE(m, num_matches); +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/backward_references_hq.h b/packages/runtime/vendor/brotli/c/enc/backward_references_hq.h new file mode 100644 index 000000000..4aa270674 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/backward_references_hq.h @@ -0,0 +1,92 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function to find backward reference copies. */ + +#ifndef BROTLI_ENC_BACKWARD_REFERENCES_HQ_H_ +#define BROTLI_ENC_BACKWARD_REFERENCES_HQ_H_ + +#include "../common/context.h" +#include "../common/platform.h" +#include "command.h" +#include "hash.h" +#include "memory.h" +#include "params.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +BROTLI_INTERNAL void BrotliCreateZopfliBackwardReferences(MemoryManager* m, + size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); + +BROTLI_INTERNAL void BrotliCreateHqZopfliBackwardReferences(MemoryManager* m, + size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals); + +typedef struct ZopfliNode { + /* Best length to get up to this byte (not including this byte itself) + highest 7 bit is used to reconstruct the length code. */ + uint32_t length; + /* Distance associated with the length. */ + uint32_t distance; + /* Number of literal inserts before this copy; highest 5 bits contain + distance short code + 1 (or zero if no short code). */ + uint32_t dcode_insert_length; + + /* This union holds information used by dynamic-programming. During forward + pass |cost| it used to store the goal function. When node is processed its + |cost| is invalidated in favor of |shortcut|. On path back-tracing pass + |next| is assigned the offset to next node on the path. */ + union { + /* Smallest cost to get to this byte from the beginning, as found so far. */ + float cost; + /* Offset to the next node on the path. Equals to command_length() of the + next node on the path. For last node equals to BROTLI_UINT32_MAX */ + uint32_t next; + /* Node position that provides next distance for distance cache. */ + uint32_t shortcut; + } u; +} ZopfliNode; + +BROTLI_INTERNAL void BrotliInitZopfliNodes(ZopfliNode* array, size_t length); + +/* Computes the shortest path of commands from position to at most + position + num_bytes. + + On return, path->size() is the number of commands found and path[i] is the + length of the i-th command (copy length plus insert length). + Note that the sum of the lengths of all commands can be less than num_bytes. + + On return, the nodes[0..num_bytes] array will have the following + "ZopfliNode array invariant": + For each i in [1..num_bytes], if nodes[i].cost < kInfinity, then + (1) nodes[i].copy_length() >= 2 + (2) nodes[i].command_length() <= i and + (3) nodes[i - nodes[i].command_length()].cost < kInfinity */ +BROTLI_INTERNAL size_t BrotliZopfliComputeShortestPath( + MemoryManager* m, size_t num_bytes, + size_t position, const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + const int* dist_cache, Hasher* hasher, ZopfliNode* nodes); + +BROTLI_INTERNAL void BrotliZopfliCreateCommands( + const size_t num_bytes, const size_t block_start, const ZopfliNode* nodes, + int* dist_cache, size_t* last_insert_len, const BrotliEncoderParams* params, + Command* commands, size_t* num_literals); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_BACKWARD_REFERENCES_HQ_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/backward_references_inc.h b/packages/runtime/vendor/brotli/c/enc/backward_references_inc.h new file mode 100644 index 000000000..752c12e9f --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/backward_references_inc.h @@ -0,0 +1,189 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: EXPORT_FN, FN */ + +static BROTLI_NOINLINE void EXPORT_FN(CreateBackwardReferences)( + size_t num_bytes, size_t position, + const uint8_t* ringbuffer, size_t ringbuffer_mask, + ContextLut literal_context_lut, const BrotliEncoderParams* params, + Hasher* hasher, int* dist_cache, size_t* last_insert_len, + Command* commands, size_t* num_commands, size_t* num_literals) { + HASHER()* privat = &hasher->privat.FN(_); + /* Set maximum distance, see section 9.1. of the spec. */ + const size_t max_backward_limit = BROTLI_MAX_BACKWARD_LIMIT(params->lgwin); + const size_t position_offset = params->stream_offset; + + const Command* const orig_commands = commands; + size_t insert_length = *last_insert_len; + const size_t pos_end = position + num_bytes; + const size_t store_end = num_bytes >= FN(StoreLookahead)() ? + position + num_bytes - FN(StoreLookahead)() + 1 : position; + + /* For speed up heuristics for random data. */ + const size_t random_heuristics_window_size = + LiteralSpreeLengthForSparseSearch(params); + size_t apply_random_heuristics = position + random_heuristics_window_size; + const size_t gap = params->dictionary.compound.total_size; + + /* Minimum score to accept a backward reference. */ + const score_t kMinScore = BROTLI_SCORE_BASE + 100; + + FN(PrepareDistanceCache)(privat, dist_cache); + + while (position + FN(HashTypeLength)() < pos_end) { + size_t max_length = pos_end - position; + size_t max_distance = BROTLI_MIN(size_t, position, max_backward_limit); + size_t dictionary_start = BROTLI_MIN(size_t, + position + position_offset, max_backward_limit); + HasherSearchResult sr; + int dict_id = 0; + uint8_t p1 = 0; + uint8_t p2 = 0; + if (params->dictionary.contextual.context_based) { + p1 = position >= 1 ? + ringbuffer[(size_t)(position - 1) & ringbuffer_mask] : 0; + p2 = position >= 2 ? + ringbuffer[(size_t)(position - 2) & ringbuffer_mask] : 0; + dict_id = params->dictionary.contextual.context_map[ + BROTLI_CONTEXT(p1, p2, literal_context_lut)]; + } + sr.len = 0; + sr.len_code_delta = 0; + sr.distance = 0; + sr.score = kMinScore; + FN(FindLongestMatch)(privat, params->dictionary.contextual.dict[dict_id], + ringbuffer, ringbuffer_mask, dist_cache, position, max_length, + max_distance, dictionary_start + gap, params->dist.max_distance, &sr); + if (ENABLE_COMPOUND_DICTIONARY) { + LookupCompoundDictionaryMatch(¶ms->dictionary.compound, ringbuffer, + ringbuffer_mask, dist_cache, position, max_length, + dictionary_start, params->dist.max_distance, &sr); + } + if (sr.score > kMinScore) { + /* Found a match. Let's look for something even better ahead. */ + int delayed_backward_references_in_row = 0; + --max_length; + for (;; --max_length) { + const score_t cost_diff_lazy = 175; + HasherSearchResult sr2; + sr2.len = params->quality < MIN_QUALITY_FOR_EXTENSIVE_REFERENCE_SEARCH ? + BROTLI_MIN(size_t, sr.len - 1, max_length) : 0; + sr2.len_code_delta = 0; + sr2.distance = 0; + sr2.score = kMinScore; + max_distance = BROTLI_MIN(size_t, position + 1, max_backward_limit); + dictionary_start = BROTLI_MIN(size_t, + position + 1 + position_offset, max_backward_limit); + if (params->dictionary.contextual.context_based) { + p2 = p1; + p1 = ringbuffer[position & ringbuffer_mask]; + dict_id = params->dictionary.contextual.context_map[ + BROTLI_CONTEXT(p1, p2, literal_context_lut)]; + } + FN(FindLongestMatch)(privat, + params->dictionary.contextual.dict[dict_id], + ringbuffer, ringbuffer_mask, dist_cache, position + 1, max_length, + max_distance, dictionary_start + gap, params->dist.max_distance, + &sr2); + if (ENABLE_COMPOUND_DICTIONARY) { + LookupCompoundDictionaryMatch( + ¶ms->dictionary.compound, ringbuffer, + ringbuffer_mask, dist_cache, position + 1, max_length, + dictionary_start, params->dist.max_distance, &sr2); + } + if (sr2.score >= sr.score + cost_diff_lazy) { + /* Ok, let's just write one byte for now and start a match from the + next byte. */ + ++position; + ++insert_length; + sr = sr2; + if (++delayed_backward_references_in_row < 4 && + position + FN(HashTypeLength)() < pos_end) { + continue; + } + } + break; + } + apply_random_heuristics = + position + 2 * sr.len + random_heuristics_window_size; + dictionary_start = BROTLI_MIN(size_t, + position + position_offset, max_backward_limit); + { + /* The first 16 codes are special short-codes, + and the minimum offset is 1. */ + size_t distance_code = ComputeDistanceCode( + sr.distance, dictionary_start + gap, dist_cache); + if ((sr.distance <= (dictionary_start + gap)) && distance_code > 0) { + dist_cache[3] = dist_cache[2]; + dist_cache[2] = dist_cache[1]; + dist_cache[1] = dist_cache[0]; + dist_cache[0] = (int)sr.distance; + FN(PrepareDistanceCache)(privat, dist_cache); + } + InitCommand(commands++, ¶ms->dist, insert_length, + sr.len, sr.len_code_delta, distance_code); + } + *num_literals += insert_length; + insert_length = 0; + /* Put the hash keys into the table, if there are enough bytes left. + Depending on the hasher implementation, it can push all positions + in the given range or only a subset of them. + Avoid hash poisoning with RLE data. */ + { + size_t range_start = position + 2; + size_t range_end = BROTLI_MIN(size_t, position + sr.len, store_end); + if (sr.distance < (sr.len >> 2)) { + range_start = BROTLI_MIN(size_t, range_end, BROTLI_MAX(size_t, + range_start, position + sr.len - (sr.distance << 2))); + } + FN(StoreRange)(privat, ringbuffer, ringbuffer_mask, range_start, + range_end); + } + position += sr.len; + } else { + ++insert_length; + ++position; + /* If we have not seen matches for a long time, we can skip some + match lookups. Unsuccessful match lookups are very very expensive + and this kind of a heuristic speeds up compression quite + a lot. */ + if (position > apply_random_heuristics) { + /* Going through uncompressible data, jump. */ + if (position > + apply_random_heuristics + 4 * random_heuristics_window_size) { + /* It is quite a long time since we saw a copy, so we assume + that this data is not compressible, and store hashes less + often. Hashes of non compressible data are less likely to + turn out to be useful in the future, too, so we store less of + them to not to flood out the hash table of good compressible + data. */ + const size_t kMargin = + BROTLI_MAX(size_t, FN(StoreLookahead)() - 1, 4); + size_t pos_jump = + BROTLI_MIN(size_t, position + 16, pos_end - kMargin); + for (; position < pos_jump; position += 4) { + FN(Store)(privat, ringbuffer, ringbuffer_mask, position); + insert_length += 4; + } + } else { + const size_t kMargin = + BROTLI_MAX(size_t, FN(StoreLookahead)() - 1, 2); + size_t pos_jump = + BROTLI_MIN(size_t, position + 8, pos_end - kMargin); + for (; position < pos_jump; position += 2) { + FN(Store)(privat, ringbuffer, ringbuffer_mask, position); + insert_length += 2; + } + } + } + } + } + insert_length += pos_end - position; + *last_insert_len = insert_length; + *num_commands += (size_t)(commands - orig_commands); +} diff --git a/packages/runtime/vendor/brotli/c/enc/bit_cost.c b/packages/runtime/vendor/brotli/c/enc/bit_cost.c new file mode 100644 index 000000000..059f8d996 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/bit_cost.c @@ -0,0 +1,60 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions to estimate the bit cost of Huffman trees. */ + +#include "bit_cost.h" + +#include "../common/platform.h" +#include "fast_log.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +double BrotliBitsEntropy(const uint32_t* population, size_t size) { + size_t sum = 0; + double retval = 0; + const uint32_t* population_end = population + size; + size_t p; + if (size & 1) { + goto odd_number_of_elements_left; + } + while (population < population_end) { + p = *population++; + sum += p; + retval -= (double)p * FastLog2(p); + odd_number_of_elements_left: + p = *population++; + sum += p; + retval -= (double)p * FastLog2(p); + } + if (sum) retval += (double)sum * FastLog2(sum); + + if (retval < (double)sum) { + /* TODO(eustas): consider doing that per-symbol? */ + /* At least one bit per literal is needed. */ + retval = (double)sum; + } + + return retval; +} + +#define FN(X) X ## Literal +#include "bit_cost_inc.h" /* NOLINT(build/include) */ +#undef FN + +#define FN(X) X ## Command +#include "bit_cost_inc.h" /* NOLINT(build/include) */ +#undef FN + +#define FN(X) X ## Distance +#include "bit_cost_inc.h" /* NOLINT(build/include) */ +#undef FN + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/bit_cost.h b/packages/runtime/vendor/brotli/c/enc/bit_cost.h new file mode 100644 index 000000000..90313c4c3 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/bit_cost.h @@ -0,0 +1,32 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions to estimate the bit cost of Huffman trees. */ + +#ifndef BROTLI_ENC_BIT_COST_H_ +#define BROTLI_ENC_BIT_COST_H_ + +#include "../common/platform.h" +#include "histogram.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +BROTLI_INTERNAL double BrotliBitsEntropy( + const uint32_t* population, size_t size); +BROTLI_INTERNAL double BrotliPopulationCostLiteral( + const HistogramLiteral* histogram); +BROTLI_INTERNAL double BrotliPopulationCostCommand( + const HistogramCommand* histogram); +BROTLI_INTERNAL double BrotliPopulationCostDistance( + const HistogramDistance* histogram); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_BIT_COST_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/bit_cost_inc.h b/packages/runtime/vendor/brotli/c/enc/bit_cost_inc.h new file mode 100644 index 000000000..8e67f2503 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/bit_cost_inc.h @@ -0,0 +1,127 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN */ + +#define HistogramType FN(Histogram) + +double FN(BrotliPopulationCost)(const HistogramType* histogram) { + static const double kOneSymbolHistogramCost = 12; + static const double kTwoSymbolHistogramCost = 20; + static const double kThreeSymbolHistogramCost = 28; + static const double kFourSymbolHistogramCost = 37; + const size_t data_size = FN(HistogramDataSize)(); + int count = 0; + size_t s[5]; + double bits = 0.0; + size_t i; + if (histogram->total_count_ == 0) { + return kOneSymbolHistogramCost; + } + for (i = 0; i < data_size; ++i) { + if (histogram->data_[i] > 0) { + s[count] = i; + ++count; + if (count > 4) break; + } + } + if (count == 1) { + return kOneSymbolHistogramCost; + } + if (count == 2) { + return (kTwoSymbolHistogramCost + (double)histogram->total_count_); + } + if (count == 3) { + const uint32_t histo0 = histogram->data_[s[0]]; + const uint32_t histo1 = histogram->data_[s[1]]; + const uint32_t histo2 = histogram->data_[s[2]]; + const uint32_t histomax = + BROTLI_MAX(uint32_t, histo0, BROTLI_MAX(uint32_t, histo1, histo2)); + return (kThreeSymbolHistogramCost + + 2 * (histo0 + histo1 + histo2) - histomax); + } + if (count == 4) { + uint32_t histo[4]; + uint32_t h23; + uint32_t histomax; + for (i = 0; i < 4; ++i) { + histo[i] = histogram->data_[s[i]]; + } + /* Sort */ + for (i = 0; i < 4; ++i) { + size_t j; + for (j = i + 1; j < 4; ++j) { + if (histo[j] > histo[i]) { + BROTLI_SWAP(uint32_t, histo, j, i); + } + } + } + h23 = histo[2] + histo[3]; + histomax = BROTLI_MAX(uint32_t, h23, histo[0]); + return (kFourSymbolHistogramCost + + 3 * h23 + 2 * (histo[0] + histo[1]) - histomax); + } + + { + /* In this loop we compute the entropy of the histogram and simultaneously + build a simplified histogram of the code length codes where we use the + zero repeat code 17, but we don't use the non-zero repeat code 16. */ + size_t max_depth = 1; + uint32_t depth_histo[BROTLI_CODE_LENGTH_CODES] = { 0 }; + const double log2total = FastLog2(histogram->total_count_); + for (i = 0; i < data_size;) { + if (histogram->data_[i] > 0) { + /* Compute -log2(P(symbol)) = -log2(count(symbol)/total_count) = + = log2(total_count) - log2(count(symbol)) */ + double log2p = log2total - FastLog2(histogram->data_[i]); + /* Approximate the bit depth by round(-log2(P(symbol))) */ + size_t depth = (size_t)(log2p + 0.5); + bits += histogram->data_[i] * log2p; + if (depth > 15) { + depth = 15; + } + if (depth > max_depth) { + max_depth = depth; + } + ++depth_histo[depth]; + ++i; + } else { + /* Compute the run length of zeros and add the appropriate number of 0 + and 17 code length codes to the code length code histogram. */ + uint32_t reps = 1; + size_t k; + for (k = i + 1; k < data_size && histogram->data_[k] == 0; ++k) { + ++reps; + } + i += reps; + if (i == data_size) { + /* Don't add any cost for the last zero run, since these are encoded + only implicitly. */ + break; + } + if (reps < 3) { + depth_histo[0] += reps; + } else { + reps -= 2; + while (reps > 0) { + ++depth_histo[BROTLI_REPEAT_ZERO_CODE_LENGTH]; + /* Add the 3 extra bits for the 17 code length code. */ + bits += 3; + reps >>= 3; + } + } + } + } + /* Add the estimated encoding cost of the code length code histogram. */ + bits += (double)(18 + 2 * max_depth); + /* Add the entropy of the code length code histogram. */ + bits += BrotliBitsEntropy(depth_histo, BROTLI_CODE_LENGTH_CODES); + } + return bits; +} + +#undef HistogramType diff --git a/packages/runtime/vendor/brotli/c/enc/block_encoder_inc.h b/packages/runtime/vendor/brotli/c/enc/block_encoder_inc.h new file mode 100644 index 000000000..8cbd5eac6 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/block_encoder_inc.h @@ -0,0 +1,34 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN */ + +#define HistogramType FN(Histogram) + +/* Creates entropy codes for all block types and stores them to the bit + stream. */ +static void FN(BuildAndStoreEntropyCodes)(MemoryManager* m, BlockEncoder* self, + const HistogramType* histograms, const size_t histograms_size, + const size_t alphabet_size, HuffmanTree* tree, + size_t* storage_ix, uint8_t* storage) { + const size_t table_size = histograms_size * self->histogram_length_; + self->depths_ = BROTLI_ALLOC(m, uint8_t, table_size); + self->bits_ = BROTLI_ALLOC(m, uint16_t, table_size); + if (BROTLI_IS_OOM(m)) return; + + { + size_t i; + for (i = 0; i < histograms_size; ++i) { + size_t ix = i * self->histogram_length_; + BuildAndStoreHuffmanTree(&histograms[i].data_[0], self->histogram_length_, + alphabet_size, tree, &self->depths_[ix], &self->bits_[ix], + storage_ix, storage); + } + } +} + +#undef HistogramType diff --git a/packages/runtime/vendor/brotli/c/enc/block_splitter.c b/packages/runtime/vendor/brotli/c/enc/block_splitter.c new file mode 100644 index 000000000..13e924f09 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/block_splitter.c @@ -0,0 +1,214 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Block split point selection utilities. */ + +#include "block_splitter.h" + +#include "../common/platform.h" +#include "bit_cost.h" +#include "cluster.h" +#include "command.h" +#include "fast_log.h" +#include "histogram.h" +#include "memory.h" +#include "quality.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static const size_t kMaxLiteralHistograms = 100; +static const size_t kMaxCommandHistograms = 50; +static const double kLiteralBlockSwitchCost = 28.1; +static const double kCommandBlockSwitchCost = 13.5; +static const double kDistanceBlockSwitchCost = 14.6; +static const size_t kLiteralStrideLength = 70; +static const size_t kCommandStrideLength = 40; +static const size_t kDistanceStrideLength = 40; +static const size_t kSymbolsPerLiteralHistogram = 544; +static const size_t kSymbolsPerCommandHistogram = 530; +static const size_t kSymbolsPerDistanceHistogram = 544; +static const size_t kMinLengthForBlockSplitting = 128; +static const size_t kIterMulForRefining = 2; +static const size_t kMinItersForRefining = 100; + +static size_t CountLiterals(const Command* cmds, const size_t num_commands) { + /* Count how many we have. */ + size_t total_length = 0; + size_t i; + for (i = 0; i < num_commands; ++i) { + total_length += cmds[i].insert_len_; + } + return total_length; +} + +static void CopyLiteralsToByteArray(const Command* cmds, + const size_t num_commands, + const uint8_t* data, + const size_t offset, + const size_t mask, + uint8_t* literals) { + size_t pos = 0; + size_t from_pos = offset & mask; + size_t i; + for (i = 0; i < num_commands; ++i) { + size_t insert_len = cmds[i].insert_len_; + if (from_pos + insert_len > mask) { + size_t head_size = mask + 1 - from_pos; + memcpy(literals + pos, data + from_pos, head_size); + from_pos = 0; + pos += head_size; + insert_len -= head_size; + } + if (insert_len > 0) { + memcpy(literals + pos, data + from_pos, insert_len); + pos += insert_len; + } + from_pos = (from_pos + insert_len + CommandCopyLen(&cmds[i])) & mask; + } +} + +static BROTLI_INLINE uint32_t MyRand(uint32_t* seed) { + /* Initial seed should be 7. In this case, loop length is (1 << 29). */ + *seed *= 16807U; + return *seed; +} + +static BROTLI_INLINE double BitCost(size_t count) { + return count == 0 ? -2.0 : FastLog2(count); +} + +#define HISTOGRAMS_PER_BATCH 64 +#define CLUSTERS_PER_BATCH 16 + +#define FN(X) X ## Literal +#define DataType uint8_t +/* NOLINTNEXTLINE(build/include) */ +#include "block_splitter_inc.h" +#undef DataType +#undef FN + +#define FN(X) X ## Command +#define DataType uint16_t +/* NOLINTNEXTLINE(build/include) */ +#include "block_splitter_inc.h" +#undef FN + +#define FN(X) X ## Distance +/* NOLINTNEXTLINE(build/include) */ +#include "block_splitter_inc.h" +#undef DataType +#undef FN + +void BrotliInitBlockSplit(BlockSplit* self) { + self->num_types = 0; + self->num_blocks = 0; + self->types = 0; + self->lengths = 0; + self->types_alloc_size = 0; + self->lengths_alloc_size = 0; +} + +void BrotliDestroyBlockSplit(MemoryManager* m, BlockSplit* self) { + BROTLI_FREE(m, self->types); + BROTLI_FREE(m, self->lengths); +} + +/* Extracts literals, command distance and prefix codes, then applies + * SplitByteVector to create partitioning. */ +void BrotliSplitBlock(MemoryManager* m, + const Command* cmds, + const size_t num_commands, + const uint8_t* data, + const size_t pos, + const size_t mask, + const BrotliEncoderParams* params, + BlockSplit* literal_split, + BlockSplit* insert_and_copy_split, + BlockSplit* dist_split) { + { + size_t literals_count = CountLiterals(cmds, num_commands); + uint8_t* literals = BROTLI_ALLOC(m, uint8_t, literals_count); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literals)) return; + /* Create a continuous array of literals. */ + CopyLiteralsToByteArray(cmds, num_commands, data, pos, mask, literals); + /* Create the block split on the array of literals. + * Literal histograms can have alphabet size up to 256. + * Though, to accommodate context modeling, less than half of maximum size + * is allowed. */ + SplitByteVectorLiteral( + m, literals, literals_count, + kSymbolsPerLiteralHistogram, kMaxLiteralHistograms, + kLiteralStrideLength, kLiteralBlockSwitchCost, params, + literal_split); + if (BROTLI_IS_OOM(m)) return; + BROTLI_FREE(m, literals); + /* NB: this might be a good place for injecting extra splitting without + * increasing encoder complexity; however, output partition would be less + * optimal than one produced with forced splitting inside + * SplitByteVector (FindBlocks / ClusterBlocks). */ + } + + { + /* Compute prefix codes for commands. */ + uint16_t* insert_and_copy_codes = BROTLI_ALLOC(m, uint16_t, num_commands); + size_t i; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(insert_and_copy_codes)) return; + for (i = 0; i < num_commands; ++i) { + insert_and_copy_codes[i] = cmds[i].cmd_prefix_; + } + /* Create the block split on the array of command prefixes. */ + SplitByteVectorCommand( + m, insert_and_copy_codes, num_commands, + kSymbolsPerCommandHistogram, kMaxCommandHistograms, + kCommandStrideLength, kCommandBlockSwitchCost, params, + insert_and_copy_split); + if (BROTLI_IS_OOM(m)) return; + /* TODO(eustas): reuse for distances? */ + BROTLI_FREE(m, insert_and_copy_codes); + } + + { + /* Create a continuous array of distance prefixes. */ + uint16_t* distance_prefixes = BROTLI_ALLOC(m, uint16_t, num_commands); + size_t j = 0; + size_t i; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(distance_prefixes)) return; + for (i = 0; i < num_commands; ++i) { + const Command* cmd = &cmds[i]; + if (CommandCopyLen(cmd) && cmd->cmd_prefix_ >= 128) { + distance_prefixes[j++] = cmd->dist_prefix_ & 0x3FF; + } + } + /* Create the block split on the array of distance prefixes. */ + SplitByteVectorDistance( + m, distance_prefixes, j, + kSymbolsPerDistanceHistogram, kMaxCommandHistograms, + kDistanceStrideLength, kDistanceBlockSwitchCost, params, + dist_split); + if (BROTLI_IS_OOM(m)) return; + BROTLI_FREE(m, distance_prefixes); + } +} + +#if defined(BROTLI_TEST) +size_t BrotliCountLiteralsForTest(const Command*, size_t); +size_t BrotliCountLiteralsForTest(const Command* cmds, size_t num_commands) { + return CountLiterals(cmds, num_commands); +} +void BrotliCopyLiteralsToByteArrayForTest( + const Command*, size_t, const uint8_t*, size_t, size_t, uint8_t*); +void BrotliCopyLiteralsToByteArrayForTest(const Command* cmds, + size_t num_commands, const uint8_t* data, size_t offset, size_t mask, + uint8_t* literals) { + CopyLiteralsToByteArray(cmds, num_commands, data, offset, mask, literals); +} +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/block_splitter.h b/packages/runtime/vendor/brotli/c/enc/block_splitter.h new file mode 100644 index 000000000..c927794eb --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/block_splitter.h @@ -0,0 +1,49 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Block split point selection utilities. */ + +#ifndef BROTLI_ENC_BLOCK_SPLITTER_H_ +#define BROTLI_ENC_BLOCK_SPLITTER_H_ + +#include "../common/platform.h" +#include "command.h" +#include "memory.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct BlockSplit { + size_t num_types; /* Amount of distinct types */ + size_t num_blocks; /* Amount of values in types and length */ + uint8_t* types; + uint32_t* lengths; + + size_t types_alloc_size; + size_t lengths_alloc_size; +} BlockSplit; + +BROTLI_INTERNAL void BrotliInitBlockSplit(BlockSplit* self); +BROTLI_INTERNAL void BrotliDestroyBlockSplit(MemoryManager* m, + BlockSplit* self); + +BROTLI_INTERNAL void BrotliSplitBlock(MemoryManager* m, + const Command* cmds, + const size_t num_commands, + const uint8_t* data, + const size_t offset, + const size_t mask, + const BrotliEncoderParams* params, + BlockSplit* literal_split, + BlockSplit* insert_and_copy_split, + BlockSplit* dist_split); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_BLOCK_SPLITTER_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/block_splitter_inc.h b/packages/runtime/vendor/brotli/c/enc/block_splitter_inc.h new file mode 100644 index 000000000..5e34cb9c9 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/block_splitter_inc.h @@ -0,0 +1,487 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN, DataType */ + +#define HistogramType FN(Histogram) + +static void FN(InitialEntropyCodes)(const DataType* data, size_t length, + size_t stride, + size_t num_histograms, + HistogramType* histograms) { + uint32_t seed = 7; + size_t block_length = length / num_histograms; + size_t i; + FN(ClearHistograms)(histograms, num_histograms); + for (i = 0; i < num_histograms; ++i) { + size_t pos = length * i / num_histograms; + if (i != 0) { + pos += MyRand(&seed) % block_length; + } + if (pos + stride >= length) { + pos = length - stride - 1; + } + FN(HistogramAddVector)(&histograms[i], data + pos, stride); + } +} + +static void FN(RandomSample)(uint32_t* seed, + const DataType* data, + size_t length, + size_t stride, + HistogramType* sample) { + size_t pos = 0; + if (stride >= length) { + stride = length; + } else { + pos = MyRand(seed) % (length - stride + 1); + } + FN(HistogramAddVector)(sample, data + pos, stride); +} + +static void FN(RefineEntropyCodes)(const DataType* data, size_t length, + size_t stride, + size_t num_histograms, + HistogramType* histograms, + HistogramType* tmp) { + size_t iters = + kIterMulForRefining * length / stride + kMinItersForRefining; + uint32_t seed = 7; + size_t iter; + iters = ((iters + num_histograms - 1) / num_histograms) * num_histograms; + for (iter = 0; iter < iters; ++iter) { + FN(HistogramClear)(tmp); + FN(RandomSample)(&seed, data, length, stride, tmp); + FN(HistogramAddHistogram)(&histograms[iter % num_histograms], tmp); + } +} + +/* Assigns a block id from the range [0, num_histograms) to each data element + in data[0..length) and fills in block_id[0..length) with the assigned values. + Returns the number of blocks, i.e. one plus the number of block switches. */ +static size_t FN(FindBlocks)(const DataType* data, const size_t length, + const double block_switch_bitcost, + const size_t num_histograms, + const HistogramType* histograms, + double* insert_cost, + double* cost, + uint8_t* switch_signal, + uint8_t* block_id) { + const size_t alphabet_size = FN(HistogramDataSize)(); + const size_t bitmap_len = (num_histograms + 7) >> 3; + size_t num_blocks = 1; + size_t byte_ix; + size_t i; + size_t j; + BROTLI_DCHECK(num_histograms <= 256); + + /* Trivial case: single histogram -> single block type. */ + if (num_histograms <= 1) { + for (i = 0; i < length; ++i) { + block_id[i] = 0; + } + return 1; + } + + /* Fill bitcost for each symbol of all histograms. + * Non-existing symbol cost: 2 + log2(total_count). + * Regular symbol cost: -log2(symbol_count / total_count). */ + memset(insert_cost, 0, + sizeof(insert_cost[0]) * alphabet_size * num_histograms); + for (i = 0; i < num_histograms; ++i) { + insert_cost[i] = FastLog2((uint32_t)histograms[i].total_count_); + } + for (i = alphabet_size; i != 0;) { + /* Reverse order to use the 0-th row as a temporary storage. */ + --i; + for (j = 0; j < num_histograms; ++j) { + insert_cost[i * num_histograms + j] = + insert_cost[j] - BitCost(histograms[j].data_[i]); + } + } + + /* After each iteration of this loop, cost[k] will contain the difference + between the minimum cost of arriving at the current byte position using + entropy code k, and the minimum cost of arriving at the current byte + position. This difference is capped at the block switch cost, and if it + reaches block switch cost, it means that when we trace back from the last + position, we need to switch here. */ + memset(cost, 0, sizeof(cost[0]) * num_histograms); + memset(switch_signal, 0, sizeof(switch_signal[0]) * length * bitmap_len); + for (byte_ix = 0; byte_ix < length; ++byte_ix) { + size_t ix = byte_ix * bitmap_len; + size_t symbol = data[byte_ix]; + size_t insert_cost_ix = symbol * num_histograms; + double min_cost = 1e99; + double block_switch_cost = block_switch_bitcost; + static const size_t prologue_length = 2000; + static const double multiplier = 0.07 / 2000; + size_t k; + for (k = 0; k < num_histograms; ++k) { + /* We are coding the symbol with entropy code k. */ + cost[k] += insert_cost[insert_cost_ix + k]; + if (cost[k] < min_cost) { + min_cost = cost[k]; + block_id[byte_ix] = (uint8_t)k; + } + } + /* More blocks for the beginning. */ + if (byte_ix < prologue_length) { + block_switch_cost *= 0.77 + multiplier * (double)byte_ix; + } + for (k = 0; k < num_histograms; ++k) { + cost[k] -= min_cost; + if (cost[k] >= block_switch_cost) { + const uint8_t mask = (uint8_t)(1u << (k & 7)); + cost[k] = block_switch_cost; + BROTLI_DCHECK((k >> 3) < bitmap_len); + switch_signal[ix + (k >> 3)] |= mask; + } + } + } + + byte_ix = length - 1; + { /* Trace back from the last position and switch at the marked places. */ + size_t ix = byte_ix * bitmap_len; + uint8_t cur_id = block_id[byte_ix]; + while (byte_ix > 0) { + const uint8_t mask = (uint8_t)(1u << (cur_id & 7)); + BROTLI_DCHECK(((size_t)cur_id >> 3) < bitmap_len); + --byte_ix; + ix -= bitmap_len; + if (switch_signal[ix + (cur_id >> 3)] & mask) { + if (cur_id != block_id[byte_ix]) { + cur_id = block_id[byte_ix]; + ++num_blocks; + } + } + block_id[byte_ix] = cur_id; + } + } + return num_blocks; +} + +static size_t FN(RemapBlockIds)(uint8_t* block_ids, const size_t length, + uint16_t* new_id, const size_t num_histograms) { + static const uint16_t kInvalidId = 256; + uint16_t next_id = 0; + size_t i; + for (i = 0; i < num_histograms; ++i) { + new_id[i] = kInvalidId; + } + for (i = 0; i < length; ++i) { + BROTLI_DCHECK(block_ids[i] < num_histograms); + if (new_id[block_ids[i]] == kInvalidId) { + new_id[block_ids[i]] = next_id++; + } + } + for (i = 0; i < length; ++i) { + block_ids[i] = (uint8_t)new_id[block_ids[i]]; + BROTLI_DCHECK(block_ids[i] < num_histograms); + } + BROTLI_DCHECK(next_id <= num_histograms); + return next_id; +} + +static void FN(BuildBlockHistograms)(const DataType* data, const size_t length, + const uint8_t* block_ids, + const size_t num_histograms, + HistogramType* histograms) { + size_t i; + FN(ClearHistograms)(histograms, num_histograms); + for (i = 0; i < length; ++i) { + FN(HistogramAdd)(&histograms[block_ids[i]], data[i]); + } +} + +/* Given the initial partitioning build partitioning with limited number + * of histograms (and block types). */ +static void FN(ClusterBlocks)(MemoryManager* m, + const DataType* data, const size_t length, + const size_t num_blocks, + uint8_t* block_ids, + BlockSplit* split) { + uint32_t* histogram_symbols = BROTLI_ALLOC(m, uint32_t, num_blocks); + uint32_t* u32 = + BROTLI_ALLOC(m, uint32_t, num_blocks + 4 * HISTOGRAMS_PER_BATCH); + const size_t expected_num_clusters = CLUSTERS_PER_BATCH * + (num_blocks + HISTOGRAMS_PER_BATCH - 1) / HISTOGRAMS_PER_BATCH; + size_t all_histograms_size = 0; + size_t all_histograms_capacity = expected_num_clusters; + HistogramType* all_histograms = + BROTLI_ALLOC(m, HistogramType, all_histograms_capacity); + size_t cluster_size_size = 0; + size_t cluster_size_capacity = expected_num_clusters; + uint32_t* cluster_size = BROTLI_ALLOC(m, uint32_t, cluster_size_capacity); + size_t num_clusters = 0; + HistogramType* histograms = BROTLI_ALLOC(m, HistogramType, + BROTLI_MIN(size_t, num_blocks, HISTOGRAMS_PER_BATCH)); + size_t max_num_pairs = + HISTOGRAMS_PER_BATCH * HISTOGRAMS_PER_BATCH / 2; + size_t pairs_capacity = max_num_pairs + 1; + HistogramPair* pairs = BROTLI_ALLOC(m, HistogramPair, pairs_capacity); + size_t pos = 0; + uint32_t* clusters; + size_t num_final_clusters; + static const uint32_t kInvalidIndex = BROTLI_UINT32_MAX; + uint32_t* new_index; + size_t i; + uint32_t* BROTLI_RESTRICT const sizes = + u32 ? (u32 + 0 * HISTOGRAMS_PER_BATCH) : NULL; + uint32_t* BROTLI_RESTRICT const new_clusters = + u32 ? (u32 + 1 * HISTOGRAMS_PER_BATCH) : NULL; + uint32_t* BROTLI_RESTRICT const symbols = + u32 ? (u32 + 2 * HISTOGRAMS_PER_BATCH) : NULL; + uint32_t* BROTLI_RESTRICT const remap = + u32 ? (u32 + 3 * HISTOGRAMS_PER_BATCH) : NULL; + uint32_t* BROTLI_RESTRICT const block_lengths = + u32 ? (u32 + 4 * HISTOGRAMS_PER_BATCH) : NULL; + /* TODO(eustas): move to arena? */ + HistogramType* tmp = BROTLI_ALLOC(m, HistogramType, 2); + + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(histogram_symbols) || + BROTLI_IS_NULL(u32) || BROTLI_IS_NULL(all_histograms) || + BROTLI_IS_NULL(cluster_size) || BROTLI_IS_NULL(histograms) || + BROTLI_IS_NULL(pairs) || BROTLI_IS_NULL(tmp)) { + return; + } + + memset(u32, 0, (num_blocks + 4 * HISTOGRAMS_PER_BATCH) * sizeof(uint32_t)); + + /* Calculate block lengths (convert repeating values -> series length). */ + { + size_t block_idx = 0; + for (i = 0; i < length; ++i) { + BROTLI_DCHECK(block_idx < num_blocks); + ++block_lengths[block_idx]; + if (i + 1 == length || block_ids[i] != block_ids[i + 1]) { + ++block_idx; + } + } + BROTLI_DCHECK(block_idx == num_blocks); + } + + /* Pre-cluster blocks (cluster batches). */ + for (i = 0; i < num_blocks; i += HISTOGRAMS_PER_BATCH) { + const size_t num_to_combine = + BROTLI_MIN(size_t, num_blocks - i, HISTOGRAMS_PER_BATCH); + size_t num_new_clusters; + size_t j; + for (j = 0; j < num_to_combine; ++j) { + size_t k; + size_t block_length = block_lengths[i + j]; + FN(HistogramClear)(&histograms[j]); + for (k = 0; k < block_length; ++k) { + FN(HistogramAdd)(&histograms[j], data[pos++]); + } + histograms[j].bit_cost_ = FN(BrotliPopulationCost)(&histograms[j]); + new_clusters[j] = (uint32_t)j; + symbols[j] = (uint32_t)j; + sizes[j] = 1; + } + num_new_clusters = FN(BrotliHistogramCombine)( + histograms, tmp, sizes, symbols, new_clusters, pairs, num_to_combine, + num_to_combine, HISTOGRAMS_PER_BATCH, max_num_pairs); + BROTLI_ENSURE_CAPACITY(m, HistogramType, all_histograms, + all_histograms_capacity, all_histograms_size + num_new_clusters); + BROTLI_ENSURE_CAPACITY(m, uint32_t, cluster_size, + cluster_size_capacity, cluster_size_size + num_new_clusters); + if (BROTLI_IS_OOM(m)) return; + for (j = 0; j < num_new_clusters; ++j) { + all_histograms[all_histograms_size++] = histograms[new_clusters[j]]; + cluster_size[cluster_size_size++] = sizes[new_clusters[j]]; + remap[new_clusters[j]] = (uint32_t)j; + } + for (j = 0; j < num_to_combine; ++j) { + histogram_symbols[i + j] = (uint32_t)num_clusters + remap[symbols[j]]; + } + num_clusters += num_new_clusters; + BROTLI_DCHECK(num_clusters == cluster_size_size); + BROTLI_DCHECK(num_clusters == all_histograms_size); + } + BROTLI_FREE(m, histograms); + + /* Final clustering. */ + max_num_pairs = + BROTLI_MIN(size_t, 64 * num_clusters, (num_clusters / 2) * num_clusters); + if (pairs_capacity < max_num_pairs + 1) { + BROTLI_FREE(m, pairs); + pairs = BROTLI_ALLOC(m, HistogramPair, max_num_pairs + 1); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(pairs)) return; + } + clusters = BROTLI_ALLOC(m, uint32_t, num_clusters); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(clusters)) return; + for (i = 0; i < num_clusters; ++i) { + clusters[i] = (uint32_t)i; + } + num_final_clusters = FN(BrotliHistogramCombine)( + all_histograms, tmp, cluster_size, histogram_symbols, clusters, pairs, + num_clusters, num_blocks, BROTLI_MAX_NUMBER_OF_BLOCK_TYPES, + max_num_pairs); + BROTLI_FREE(m, pairs); + BROTLI_FREE(m, cluster_size); + + /* Assign blocks to final histograms. */ + new_index = BROTLI_ALLOC(m, uint32_t, num_clusters); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_index)) return; + for (i = 0; i < num_clusters; ++i) new_index[i] = kInvalidIndex; + pos = 0; + { + uint32_t next_index = 0; + for (i = 0; i < num_blocks; ++i) { + size_t j; + uint32_t best_out; + double best_bits; + FN(HistogramClear)(tmp); + for (j = 0; j < block_lengths[i]; ++j) { + FN(HistogramAdd)(tmp, data[pos++]); + } + /* Among equally good histograms prefer last used. */ + /* TODO(eustas): should we give a block-switch discount here? */ + best_out = (i == 0) ? histogram_symbols[0] : histogram_symbols[i - 1]; + best_bits = FN(BrotliHistogramBitCostDistance)( + tmp, &all_histograms[best_out], tmp + 1); + for (j = 0; j < num_final_clusters; ++j) { + const double cur_bits = FN(BrotliHistogramBitCostDistance)( + tmp, &all_histograms[clusters[j]], tmp + 1); + if (cur_bits < best_bits) { + best_bits = cur_bits; + best_out = clusters[j]; + } + } + histogram_symbols[i] = best_out; + if (new_index[best_out] == kInvalidIndex) { + new_index[best_out] = next_index++; + } + } + } + BROTLI_FREE(m, tmp); + BROTLI_FREE(m, clusters); + BROTLI_FREE(m, all_histograms); + BROTLI_ENSURE_CAPACITY( + m, uint8_t, split->types, split->types_alloc_size, num_blocks); + BROTLI_ENSURE_CAPACITY( + m, uint32_t, split->lengths, split->lengths_alloc_size, num_blocks); + if (BROTLI_IS_OOM(m)) return; + + /* Rewrite final assignment to block-split. There might be less blocks + * than |num_blocks| due to clustering. */ + { + uint32_t cur_length = 0; + size_t block_idx = 0; + uint8_t max_type = 0; + for (i = 0; i < num_blocks; ++i) { + cur_length += block_lengths[i]; + if (i + 1 == num_blocks || + histogram_symbols[i] != histogram_symbols[i + 1]) { + const uint8_t id = (uint8_t)new_index[histogram_symbols[i]]; + split->types[block_idx] = id; + split->lengths[block_idx] = cur_length; + max_type = BROTLI_MAX(uint8_t, max_type, id); + cur_length = 0; + ++block_idx; + } + } + split->num_blocks = block_idx; + split->num_types = (size_t)max_type + 1; + } + BROTLI_FREE(m, new_index); + BROTLI_FREE(m, u32); + BROTLI_FREE(m, histogram_symbols); +} + +/* Create BlockSplit (partitioning) given the limits, estimates and "effort" + * parameters. + * + * NB: max_histograms is often less than number of histograms allowed by format; + * this is done intentionally, to save some "space" for context-aware + * clustering (here entropy is estimated for context-free symbols). */ +static void FN(SplitByteVector)(MemoryManager* m, + const DataType* data, const size_t length, + const size_t symbols_per_histogram, + const size_t max_histograms, + const size_t sampling_stride_length, + const double block_switch_cost, + const BrotliEncoderParams* params, + BlockSplit* split) { + const size_t data_size = FN(HistogramDataSize)(); + HistogramType* histograms; + HistogramType* tmp; + /* Calculate number of histograms; initial estimate is one histogram per + * specified amount of symbols; however, this value is capped. */ + size_t num_histograms = length / symbols_per_histogram + 1; + if (num_histograms > max_histograms) { + num_histograms = max_histograms; + } + + /* Corner case: no input. */ + if (length == 0) { + split->num_types = 1; + return; + } + + if (length < kMinLengthForBlockSplitting) { + BROTLI_ENSURE_CAPACITY(m, uint8_t, + split->types, split->types_alloc_size, split->num_blocks + 1); + BROTLI_ENSURE_CAPACITY(m, uint32_t, + split->lengths, split->lengths_alloc_size, split->num_blocks + 1); + if (BROTLI_IS_OOM(m)) return; + split->num_types = 1; + split->types[split->num_blocks] = 0; + split->lengths[split->num_blocks] = (uint32_t)length; + split->num_blocks++; + return; + } + histograms = BROTLI_ALLOC(m, HistogramType, num_histograms + 1); + tmp = histograms + num_histograms; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(histograms)) return; + /* Find good entropy codes. */ + FN(InitialEntropyCodes)(data, length, + sampling_stride_length, + num_histograms, histograms); + FN(RefineEntropyCodes)(data, length, + sampling_stride_length, + num_histograms, histograms, tmp); + { + /* Find a good path through literals with the good entropy codes. */ + uint8_t* block_ids = BROTLI_ALLOC(m, uint8_t, length); + size_t num_blocks = 0; + const size_t bitmaplen = (num_histograms + 7) >> 3; + double* insert_cost = BROTLI_ALLOC(m, double, data_size * num_histograms); + double* cost = BROTLI_ALLOC(m, double, num_histograms); + uint8_t* switch_signal = BROTLI_ALLOC(m, uint8_t, length * bitmaplen); + uint16_t* new_id = BROTLI_ALLOC(m, uint16_t, num_histograms); + const size_t iters = params->quality < HQ_ZOPFLIFICATION_QUALITY ? 3 : 10; + size_t i; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(block_ids) || + BROTLI_IS_NULL(insert_cost) || BROTLI_IS_NULL(cost) || + BROTLI_IS_NULL(switch_signal) || BROTLI_IS_NULL(new_id)) { + return; + } + for (i = 0; i < iters; ++i) { + num_blocks = FN(FindBlocks)(data, length, + block_switch_cost, + num_histograms, histograms, + insert_cost, cost, switch_signal, + block_ids); + num_histograms = FN(RemapBlockIds)(block_ids, length, + new_id, num_histograms); + FN(BuildBlockHistograms)(data, length, block_ids, + num_histograms, histograms); + } + BROTLI_FREE(m, insert_cost); + BROTLI_FREE(m, cost); + BROTLI_FREE(m, switch_signal); + BROTLI_FREE(m, new_id); + BROTLI_FREE(m, histograms); + FN(ClusterBlocks)(m, data, length, num_blocks, block_ids, split); + if (BROTLI_IS_OOM(m)) return; + BROTLI_FREE(m, block_ids); + } +} + +#undef HistogramType diff --git a/packages/runtime/vendor/brotli/c/enc/brotli_bit_stream.c b/packages/runtime/vendor/brotli/c/enc/brotli_bit_stream.c new file mode 100644 index 000000000..1e9e946fe --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/brotli_bit_stream.c @@ -0,0 +1,1337 @@ +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Brotli bit stream functions to support the low level format. There are no + compression algorithms here, just the right ordering of bits to match the + specs. */ + +#include "brotli_bit_stream.h" + +#include "../common/constants.h" +#include "../common/context.h" +#include "../common/platform.h" +#include "entropy_encode.h" +#include "entropy_encode_static.h" +#include "fast_log.h" +#include "histogram.h" +#include "memory.h" +#include "write_bits.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define MAX_HUFFMAN_TREE_SIZE (2 * BROTLI_NUM_COMMAND_SYMBOLS + 1) +/* The maximum size of Huffman dictionary for distances assuming that + NPOSTFIX = 0 and NDIRECT = 0. */ +#define MAX_SIMPLE_DISTANCE_ALPHABET_SIZE \ + BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_LARGE_MAX_DISTANCE_BITS) +/* MAX_SIMPLE_DISTANCE_ALPHABET_SIZE == 140 */ + +static BROTLI_INLINE uint32_t BlockLengthPrefixCode(uint32_t len) { + uint32_t code = (len >= 177) ? (len >= 753 ? 20 : 14) : (len >= 41 ? 7 : 0); + while (code < (BROTLI_NUM_BLOCK_LEN_SYMBOLS - 1) && + len >= _kBrotliPrefixCodeRanges[code + 1].offset) ++code; + return code; +} + +static BROTLI_INLINE void GetBlockLengthPrefixCode(uint32_t len, size_t* code, + uint32_t* n_extra, uint32_t* extra) { + *code = BlockLengthPrefixCode(len); + *n_extra = _kBrotliPrefixCodeRanges[*code].nbits; + *extra = len - _kBrotliPrefixCodeRanges[*code].offset; +} + +typedef struct BlockTypeCodeCalculator { + size_t last_type; + size_t second_last_type; +} BlockTypeCodeCalculator; + +static void InitBlockTypeCodeCalculator(BlockTypeCodeCalculator* self) { + self->last_type = 1; + self->second_last_type = 0; +} + +static BROTLI_INLINE size_t NextBlockTypeCode( + BlockTypeCodeCalculator* calculator, uint8_t type) { + size_t type_code = (type == calculator->last_type + 1) ? 1u : + (type == calculator->second_last_type) ? 0u : type + 2u; + calculator->second_last_type = calculator->last_type; + calculator->last_type = type; + return type_code; +} + +/* |nibblesbits| represents the 2 bits to encode MNIBBLES (0-3) + REQUIRES: length > 0 + REQUIRES: length <= (1 << 24) */ +static void BrotliEncodeMlen(size_t length, uint64_t* bits, + size_t* numbits, uint64_t* nibblesbits) { + size_t lg = (length == 1) ? 1 : Log2FloorNonZero((uint32_t)(length - 1)) + 1; + size_t mnibbles = (lg < 16 ? 16 : (lg + 3)) / 4; + BROTLI_DCHECK(length > 0); + BROTLI_DCHECK(length <= (1 << 24)); + BROTLI_DCHECK(lg <= 24); + *nibblesbits = mnibbles - 4; + *numbits = mnibbles * 4; + *bits = length - 1; +} + +static BROTLI_INLINE void StoreCommandExtra( + const Command* cmd, size_t* storage_ix, uint8_t* storage) { + uint32_t copylen_code = CommandCopyLenCode(cmd); + uint16_t inscode = GetInsertLengthCode(cmd->insert_len_); + uint16_t copycode = GetCopyLengthCode(copylen_code); + uint32_t insnumextra = GetInsertExtra(inscode); + uint64_t insextraval = cmd->insert_len_ - GetInsertBase(inscode); + uint64_t copyextraval = copylen_code - GetCopyBase(copycode); + uint64_t bits = (copyextraval << insnumextra) | insextraval; + BrotliWriteBits( + insnumextra + GetCopyExtra(copycode), bits, storage_ix, storage); +} + +/* Data structure that stores almost everything that is needed to encode each + block switch command. */ +typedef struct BlockSplitCode { + BlockTypeCodeCalculator type_code_calculator; + uint8_t type_depths[BROTLI_MAX_BLOCK_TYPE_SYMBOLS]; + uint16_t type_bits[BROTLI_MAX_BLOCK_TYPE_SYMBOLS]; + uint8_t length_depths[BROTLI_NUM_BLOCK_LEN_SYMBOLS]; + uint16_t length_bits[BROTLI_NUM_BLOCK_LEN_SYMBOLS]; +} BlockSplitCode; + +/* Stores a number between 0 and 255. */ +static void StoreVarLenUint8(size_t n, size_t* storage_ix, uint8_t* storage) { + if (n == 0) { + BrotliWriteBits(1, 0, storage_ix, storage); + } else { + size_t nbits = Log2FloorNonZero(n); + BrotliWriteBits(1, 1, storage_ix, storage); + BrotliWriteBits(3, nbits, storage_ix, storage); + BrotliWriteBits(nbits, n - ((size_t)1 << nbits), storage_ix, storage); + } +} + +/* Stores the compressed meta-block header. + REQUIRES: length > 0 + REQUIRES: length <= (1 << 24) */ +static void StoreCompressedMetaBlockHeader(BROTLI_BOOL is_final_block, + size_t length, + size_t* storage_ix, + uint8_t* storage) { + uint64_t lenbits; + size_t nlenbits; + uint64_t nibblesbits; + + /* Write ISLAST bit. */ + BrotliWriteBits(1, (uint64_t)is_final_block, storage_ix, storage); + /* Write ISEMPTY bit. */ + if (is_final_block) { + BrotliWriteBits(1, 0, storage_ix, storage); + } + + BrotliEncodeMlen(length, &lenbits, &nlenbits, &nibblesbits); + BrotliWriteBits(2, nibblesbits, storage_ix, storage); + BrotliWriteBits(nlenbits, lenbits, storage_ix, storage); + + if (!is_final_block) { + /* Write ISUNCOMPRESSED bit. */ + BrotliWriteBits(1, 0, storage_ix, storage); + } +} + +/* Stores the uncompressed meta-block header. + REQUIRES: length > 0 + REQUIRES: length <= (1 << 24) */ +static void BrotliStoreUncompressedMetaBlockHeader(size_t length, + size_t* storage_ix, + uint8_t* storage) { + uint64_t lenbits; + size_t nlenbits; + uint64_t nibblesbits; + + /* Write ISLAST bit. + Uncompressed block cannot be the last one, so set to 0. */ + BrotliWriteBits(1, 0, storage_ix, storage); + BrotliEncodeMlen(length, &lenbits, &nlenbits, &nibblesbits); + BrotliWriteBits(2, nibblesbits, storage_ix, storage); + BrotliWriteBits(nlenbits, lenbits, storage_ix, storage); + /* Write ISUNCOMPRESSED bit. */ + BrotliWriteBits(1, 1, storage_ix, storage); +} + +static void BrotliStoreHuffmanTreeOfHuffmanTreeToBitMask( + const int num_codes, const uint8_t* code_length_bitdepth, + size_t* storage_ix, uint8_t* storage) { + static const BROTLI_MODEL("small") + uint8_t kStorageOrder[BROTLI_CODE_LENGTH_CODES] = { + 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15 + }; + /* The bit lengths of the Huffman code over the code length alphabet + are compressed with the following static Huffman code: + Symbol Code + ------ ---- + 0 00 + 1 1110 + 2 110 + 3 01 + 4 10 + 5 1111 */ + static const BROTLI_MODEL("small") + uint8_t kHuffmanBitLengthHuffmanCodeSymbols[6] = { + 0, 7, 3, 2, 1, 15 + }; + static const BROTLI_MODEL("small") + uint8_t kHuffmanBitLengthHuffmanCodeBitLengths[6] = { + 2, 4, 3, 2, 2, 4 + }; + + size_t skip_some = 0; /* skips none. */ + + /* Throw away trailing zeros: */ + size_t codes_to_store = BROTLI_CODE_LENGTH_CODES; + if (num_codes > 1) { + for (; codes_to_store > 0; --codes_to_store) { + if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) { + break; + } + } + } + if (code_length_bitdepth[kStorageOrder[0]] == 0 && + code_length_bitdepth[kStorageOrder[1]] == 0) { + skip_some = 2; /* skips two. */ + if (code_length_bitdepth[kStorageOrder[2]] == 0) { + skip_some = 3; /* skips three. */ + } + } + BrotliWriteBits(2, skip_some, storage_ix, storage); + { + size_t i; + for (i = skip_some; i < codes_to_store; ++i) { + size_t l = code_length_bitdepth[kStorageOrder[i]]; + BrotliWriteBits(kHuffmanBitLengthHuffmanCodeBitLengths[l], + kHuffmanBitLengthHuffmanCodeSymbols[l], storage_ix, storage); + } + } +} + +static void BrotliStoreHuffmanTreeToBitMask( + const size_t huffman_tree_size, const uint8_t* huffman_tree, + const uint8_t* huffman_tree_extra_bits, const uint8_t* code_length_bitdepth, + const uint16_t* code_length_bitdepth_symbols, + size_t* BROTLI_RESTRICT storage_ix, uint8_t* BROTLI_RESTRICT storage) { + size_t i; + for (i = 0; i < huffman_tree_size; ++i) { + size_t ix = huffman_tree[i]; + BrotliWriteBits(code_length_bitdepth[ix], code_length_bitdepth_symbols[ix], + storage_ix, storage); + /* Extra bits */ + switch (ix) { + case BROTLI_REPEAT_PREVIOUS_CODE_LENGTH: + BrotliWriteBits(2, huffman_tree_extra_bits[i], storage_ix, storage); + break; + case BROTLI_REPEAT_ZERO_CODE_LENGTH: + BrotliWriteBits(3, huffman_tree_extra_bits[i], storage_ix, storage); + break; + } + } +} + +static void StoreSimpleHuffmanTree(const uint8_t* depths, + size_t symbols[4], + size_t num_symbols, + size_t max_bits, + size_t* storage_ix, uint8_t* storage) { + /* value of 1 indicates a simple Huffman code */ + BrotliWriteBits(2, 1, storage_ix, storage); + BrotliWriteBits(2, num_symbols - 1, storage_ix, storage); /* NSYM - 1 */ + + { + /* Sort */ + size_t i; + for (i = 0; i < num_symbols; i++) { + size_t j; + for (j = i + 1; j < num_symbols; j++) { + if (depths[symbols[j]] < depths[symbols[i]]) { + BROTLI_SWAP(size_t, symbols, j, i); + } + } + } + } + + if (num_symbols == 2) { + BrotliWriteBits(max_bits, symbols[0], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[1], storage_ix, storage); + } else if (num_symbols == 3) { + BrotliWriteBits(max_bits, symbols[0], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[1], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[2], storage_ix, storage); + } else { + BrotliWriteBits(max_bits, symbols[0], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[1], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[2], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[3], storage_ix, storage); + /* tree-select */ + BrotliWriteBits(1, depths[symbols[0]] == 1 ? 1 : 0, storage_ix, storage); + } +} + +/* num = alphabet size + depths = symbol depths */ +void BrotliStoreHuffmanTree(const uint8_t* depths, size_t num, + HuffmanTree* tree, + size_t* storage_ix, uint8_t* storage) { + /* Write the Huffman tree into the brotli-representation. + The command alphabet is the largest, so this allocation will fit all + alphabets. */ + /* TODO(eustas): fix me */ + uint8_t huffman_tree[BROTLI_NUM_COMMAND_SYMBOLS]; + uint8_t huffman_tree_extra_bits[BROTLI_NUM_COMMAND_SYMBOLS]; + size_t huffman_tree_size = 0; + uint8_t code_length_bitdepth[BROTLI_CODE_LENGTH_CODES] = { 0 }; + uint16_t code_length_bitdepth_symbols[BROTLI_CODE_LENGTH_CODES]; + uint32_t huffman_tree_histogram[BROTLI_CODE_LENGTH_CODES] = { 0 }; + size_t i; + int num_codes = 0; + size_t code = 0; + + BROTLI_DCHECK(num <= BROTLI_NUM_COMMAND_SYMBOLS); + + BrotliWriteHuffmanTree(depths, num, &huffman_tree_size, huffman_tree, + huffman_tree_extra_bits); + + /* Calculate the statistics of the Huffman tree in brotli-representation. */ + for (i = 0; i < huffman_tree_size; ++i) { + ++huffman_tree_histogram[huffman_tree[i]]; + } + + for (i = 0; i < BROTLI_CODE_LENGTH_CODES; ++i) { + if (huffman_tree_histogram[i]) { + if (num_codes == 0) { + code = i; + num_codes = 1; + } else if (num_codes == 1) { + num_codes = 2; + break; + } + } + } + + /* Calculate another Huffman tree to use for compressing both the + earlier Huffman tree with. */ + BrotliCreateHuffmanTree(huffman_tree_histogram, BROTLI_CODE_LENGTH_CODES, + 5, tree, code_length_bitdepth); + BrotliConvertBitDepthsToSymbols(code_length_bitdepth, + BROTLI_CODE_LENGTH_CODES, + code_length_bitdepth_symbols); + + /* Now, we have all the data, let's start storing it */ + BrotliStoreHuffmanTreeOfHuffmanTreeToBitMask(num_codes, code_length_bitdepth, + storage_ix, storage); + + if (num_codes == 1) { + code_length_bitdepth[code] = 0; + } + + /* Store the real Huffman tree now. */ + BrotliStoreHuffmanTreeToBitMask(huffman_tree_size, + huffman_tree, + huffman_tree_extra_bits, + code_length_bitdepth, + code_length_bitdepth_symbols, + storage_ix, storage); +} + +/* Builds a Huffman tree from histogram[0:length] into depth[0:length] and + bits[0:length] and stores the encoded tree to the bit stream. */ +static void BuildAndStoreHuffmanTree(const uint32_t* histogram, + const size_t histogram_length, + const size_t alphabet_size, + HuffmanTree* tree, + uint8_t* depth, + uint16_t* bits, + size_t* storage_ix, + uint8_t* storage) { + size_t count = 0; + size_t s4[4] = { 0 }; + size_t i; + size_t max_bits = 0; + for (i = 0; i < histogram_length; i++) { + if (histogram[i]) { + if (count < 4) { + s4[count] = i; + } else if (count > 4) { + break; + } + count++; + } + } + + { + size_t max_bits_counter = alphabet_size - 1; + while (max_bits_counter) { + max_bits_counter >>= 1; + ++max_bits; + } + } + + if (count <= 1) { + BrotliWriteBits(4, 1, storage_ix, storage); + BrotliWriteBits(max_bits, s4[0], storage_ix, storage); + depth[s4[0]] = 0; + bits[s4[0]] = 0; + return; + } + + memset(depth, 0, histogram_length * sizeof(depth[0])); + BrotliCreateHuffmanTree(histogram, histogram_length, 15, tree, depth); + BrotliConvertBitDepthsToSymbols(depth, histogram_length, bits); + + if (count <= 4) { + StoreSimpleHuffmanTree(depth, s4, count, max_bits, storage_ix, storage); + } else { + BrotliStoreHuffmanTree(depth, histogram_length, tree, storage_ix, storage); + } +} + +static BROTLI_INLINE BROTLI_BOOL SortHuffmanTree( + const HuffmanTree* v0, const HuffmanTree* v1) { + return TO_BROTLI_BOOL(v0->total_count_ < v1->total_count_); +} + +void BrotliBuildAndStoreHuffmanTreeFast(HuffmanTree* tree, + const uint32_t* histogram, + const size_t histogram_total, + const size_t max_bits, + uint8_t* depth, uint16_t* bits, + size_t* storage_ix, + uint8_t* storage) { + size_t count = 0; + size_t symbols[4] = { 0 }; + size_t length = 0; + size_t total = histogram_total; + while (total != 0) { + if (histogram[length]) { + if (count < 4) { + symbols[count] = length; + } + ++count; + total -= histogram[length]; + } + ++length; + } + + if (count <= 1) { + BrotliWriteBits(4, 1, storage_ix, storage); + BrotliWriteBits(max_bits, symbols[0], storage_ix, storage); + depth[symbols[0]] = 0; + bits[symbols[0]] = 0; + return; + } + + memset(depth, 0, length * sizeof(depth[0])); + { + uint32_t count_limit; + for (count_limit = 1; ; count_limit *= 2) { + HuffmanTree* node = tree; + size_t l; + for (l = length; l != 0;) { + --l; + if (histogram[l]) { + if (BROTLI_PREDICT_TRUE(histogram[l] >= count_limit)) { + InitHuffmanTree(node, histogram[l], -1, (int16_t)l); + } else { + InitHuffmanTree(node, count_limit, -1, (int16_t)l); + } + ++node; + } + } + { + const int n = (int)(node - tree); + HuffmanTree sentinel; + int i = 0; /* Points to the next leaf node. */ + int j = n + 1; /* Points to the next non-leaf node. */ + int k; + + SortHuffmanTreeItems(tree, (size_t)n, SortHuffmanTree); + /* The nodes are: + [0, n): the sorted leaf nodes that we start with. + [n]: we add a sentinel here. + [n + 1, 2n): new parent nodes are added here, starting from + (n+1). These are naturally in ascending order. + [2n]: we add a sentinel at the end as well. + There will be (2n+1) elements at the end. */ + InitHuffmanTree(&sentinel, BROTLI_UINT32_MAX, -1, -1); + *node++ = sentinel; + *node++ = sentinel; + + for (k = n - 1; k > 0; --k) { + int left, right; + if (tree[i].total_count_ <= tree[j].total_count_) { + left = i; + ++i; + } else { + left = j; + ++j; + } + if (tree[i].total_count_ <= tree[j].total_count_) { + right = i; + ++i; + } else { + right = j; + ++j; + } + /* The sentinel node becomes the parent node. */ + node[-1].total_count_ = + tree[left].total_count_ + tree[right].total_count_; + node[-1].index_left_ = (int16_t)left; + node[-1].index_right_or_value_ = (int16_t)right; + /* Add back the last sentinel node. */ + *node++ = sentinel; + } + if (BrotliSetDepth(2 * n - 1, tree, depth, 14)) { + /* We need to pack the Huffman tree in 14 bits. If this was not + successful, add fake entities to the lowest values and retry. */ + break; + } + } + } + } + BrotliConvertBitDepthsToSymbols(depth, length, bits); + if (count <= 4) { + size_t i; + /* value of 1 indicates a simple Huffman code */ + BrotliWriteBits(2, 1, storage_ix, storage); + BrotliWriteBits(2, count - 1, storage_ix, storage); /* NSYM - 1 */ + + /* Sort */ + for (i = 0; i < count; i++) { + size_t j; + for (j = i + 1; j < count; j++) { + if (depth[symbols[j]] < depth[symbols[i]]) { + BROTLI_SWAP(size_t, symbols, j, i); + } + } + } + + if (count == 2) { + BrotliWriteBits(max_bits, symbols[0], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[1], storage_ix, storage); + } else if (count == 3) { + BrotliWriteBits(max_bits, symbols[0], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[1], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[2], storage_ix, storage); + } else { + BrotliWriteBits(max_bits, symbols[0], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[1], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[2], storage_ix, storage); + BrotliWriteBits(max_bits, symbols[3], storage_ix, storage); + /* tree-select */ + BrotliWriteBits(1, depth[symbols[0]] == 1 ? 1 : 0, storage_ix, storage); + } + } else { + uint8_t previous_value = 8; + size_t i; + /* Complex Huffman Tree */ + StoreStaticCodeLengthCode(storage_ix, storage); + + /* Actual RLE coding. */ + for (i = 0; i < length;) { + const uint8_t value = depth[i]; + size_t reps = 1; + size_t k; + for (k = i + 1; k < length && depth[k] == value; ++k) { + ++reps; + } + i += reps; + if (value == 0) { + BrotliWriteBits(kZeroRepsDepth[reps], kZeroRepsBits[reps], + storage_ix, storage); + } else { + if (previous_value != value) { + BrotliWriteBits(kCodeLengthDepth[value], kCodeLengthBits[value], + storage_ix, storage); + --reps; + } + if (reps < 3) { + while (reps != 0) { + reps--; + BrotliWriteBits(kCodeLengthDepth[value], kCodeLengthBits[value], + storage_ix, storage); + } + } else { + reps -= 3; + BrotliWriteBits(kNonZeroRepsDepth[reps], kNonZeroRepsBits[reps], + storage_ix, storage); + } + previous_value = value; + } + } + } +} + +static size_t IndexOf(const uint8_t* v, size_t v_size, uint8_t value) { + size_t i = 0; + for (; i < v_size; ++i) { + if (v[i] == value) return i; + } + return i; +} + +static void MoveToFront(uint8_t* v, size_t index) { + uint8_t value = v[index]; + size_t i; + for (i = index; i != 0; --i) { + v[i] = v[i - 1]; + } + v[0] = value; +} + +static void MoveToFrontTransform(const uint32_t* BROTLI_RESTRICT v_in, + const size_t v_size, + uint32_t* v_out) { + size_t i; + uint8_t mtf[256]; + uint32_t max_value; + if (v_size == 0) { + return; + } + max_value = v_in[0]; + for (i = 1; i < v_size; ++i) { + if (v_in[i] > max_value) max_value = v_in[i]; + } + BROTLI_DCHECK(max_value < 256u); + for (i = 0; i <= max_value; ++i) { + mtf[i] = (uint8_t)i; + } + { + size_t mtf_size = max_value + 1; + for (i = 0; i < v_size; ++i) { + size_t index = IndexOf(mtf, mtf_size, (uint8_t)v_in[i]); + BROTLI_DCHECK(index < mtf_size); + v_out[i] = (uint32_t)index; + MoveToFront(mtf, index); + } + } +} + +/* Finds runs of zeros in v[0..in_size) and replaces them with a prefix code of + the run length plus extra bits (lower 9 bits is the prefix code and the rest + are the extra bits). Non-zero values in v[] are shifted by + *max_length_prefix. Will not create prefix codes bigger than the initial + value of *max_run_length_prefix. The prefix code of run length L is simply + Log2Floor(L) and the number of extra bits is the same as the prefix code. */ +static void RunLengthCodeZeros(const size_t in_size, + uint32_t* BROTLI_RESTRICT v, size_t* BROTLI_RESTRICT out_size, + uint32_t* BROTLI_RESTRICT max_run_length_prefix) { + uint32_t max_reps = 0; + size_t i; + uint32_t max_prefix; + for (i = 0; i < in_size;) { + uint32_t reps = 0; + for (; i < in_size && v[i] != 0; ++i) ; + for (; i < in_size && v[i] == 0; ++i) { + ++reps; + } + max_reps = BROTLI_MAX(uint32_t, reps, max_reps); + } + max_prefix = max_reps > 0 ? Log2FloorNonZero(max_reps) : 0; + max_prefix = BROTLI_MIN(uint32_t, max_prefix, *max_run_length_prefix); + *max_run_length_prefix = max_prefix; + *out_size = 0; + for (i = 0; i < in_size;) { + BROTLI_DCHECK(*out_size <= i); + if (v[i] != 0) { + v[*out_size] = v[i] + *max_run_length_prefix; + ++i; + ++(*out_size); + } else { + uint32_t reps = 1; + size_t k; + for (k = i + 1; k < in_size && v[k] == 0; ++k) { + ++reps; + } + i += reps; + while (reps != 0) { + if (reps < (2u << max_prefix)) { + uint32_t run_length_prefix = Log2FloorNonZero(reps); + const uint32_t extra_bits = reps - (1u << run_length_prefix); + v[*out_size] = run_length_prefix + (extra_bits << 9); + ++(*out_size); + break; + } else { + const uint32_t extra_bits = (1u << max_prefix) - 1u; + v[*out_size] = max_prefix + (extra_bits << 9); + reps -= (2u << max_prefix) - 1u; + ++(*out_size); + } + } + } + } +} + +#define SYMBOL_BITS 9 + +typedef struct EncodeContextMapArena { + uint32_t histogram[BROTLI_MAX_CONTEXT_MAP_SYMBOLS]; + uint8_t depths[BROTLI_MAX_CONTEXT_MAP_SYMBOLS]; + uint16_t bits[BROTLI_MAX_CONTEXT_MAP_SYMBOLS]; +} EncodeContextMapArena; + +static void EncodeContextMap(MemoryManager* m, + EncodeContextMapArena* arena, + const uint32_t* context_map, + size_t context_map_size, + size_t num_clusters, + HuffmanTree* tree, + size_t* storage_ix, uint8_t* storage) { + size_t i; + uint32_t* rle_symbols; + uint32_t max_run_length_prefix = 6; + size_t num_rle_symbols = 0; + uint32_t* BROTLI_RESTRICT const histogram = arena->histogram; + static const uint32_t kSymbolMask = (1u << SYMBOL_BITS) - 1u; + uint8_t* BROTLI_RESTRICT const depths = arena->depths; + uint16_t* BROTLI_RESTRICT const bits = arena->bits; + + StoreVarLenUint8(num_clusters - 1, storage_ix, storage); + + if (num_clusters == 1) { + return; + } + + rle_symbols = BROTLI_ALLOC(m, uint32_t, context_map_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(rle_symbols)) return; + MoveToFrontTransform(context_map, context_map_size, rle_symbols); + RunLengthCodeZeros(context_map_size, rle_symbols, + &num_rle_symbols, &max_run_length_prefix); + memset(histogram, 0, sizeof(arena->histogram)); + for (i = 0; i < num_rle_symbols; ++i) { + ++histogram[rle_symbols[i] & kSymbolMask]; + } + { + BROTLI_BOOL use_rle = TO_BROTLI_BOOL(max_run_length_prefix > 0); + BrotliWriteBits(1, (uint64_t)use_rle, storage_ix, storage); + if (use_rle) { + BrotliWriteBits(4, max_run_length_prefix - 1, storage_ix, storage); + } + } + BuildAndStoreHuffmanTree(histogram, num_clusters + max_run_length_prefix, + num_clusters + max_run_length_prefix, + tree, depths, bits, storage_ix, storage); + for (i = 0; i < num_rle_symbols; ++i) { + const uint32_t rle_symbol = rle_symbols[i] & kSymbolMask; + const uint32_t extra_bits_val = rle_symbols[i] >> SYMBOL_BITS; + BrotliWriteBits(depths[rle_symbol], bits[rle_symbol], storage_ix, storage); + if (rle_symbol > 0 && rle_symbol <= max_run_length_prefix) { + BrotliWriteBits(rle_symbol, extra_bits_val, storage_ix, storage); + } + } + BrotliWriteBits(1, 1, storage_ix, storage); /* use move-to-front */ + BROTLI_FREE(m, rle_symbols); +} + +/* Stores the block switch command with index block_ix to the bit stream. */ +static BROTLI_INLINE void StoreBlockSwitch(BlockSplitCode* code, + const uint32_t block_len, + const uint8_t block_type, + BROTLI_BOOL is_first_block, + size_t* storage_ix, + uint8_t* storage) { + size_t typecode = NextBlockTypeCode(&code->type_code_calculator, block_type); + size_t lencode; + uint32_t len_nextra; + uint32_t len_extra; + if (!is_first_block) { + BrotliWriteBits(code->type_depths[typecode], code->type_bits[typecode], + storage_ix, storage); + } + GetBlockLengthPrefixCode(block_len, &lencode, &len_nextra, &len_extra); + + BrotliWriteBits(code->length_depths[lencode], code->length_bits[lencode], + storage_ix, storage); + BrotliWriteBits(len_nextra, len_extra, storage_ix, storage); +} + +/* Builds a BlockSplitCode data structure from the block split given by the + vector of block types and block lengths and stores it to the bit stream. */ +static void BuildAndStoreBlockSplitCode(const uint8_t* types, + const uint32_t* lengths, + const size_t num_blocks, + const size_t num_types, + HuffmanTree* tree, + BlockSplitCode* code, + size_t* storage_ix, + uint8_t* storage) { + uint32_t type_histo[BROTLI_MAX_BLOCK_TYPE_SYMBOLS]; + uint32_t length_histo[BROTLI_NUM_BLOCK_LEN_SYMBOLS]; + size_t i; + BlockTypeCodeCalculator type_code_calculator; + memset(type_histo, 0, (num_types + 2) * sizeof(type_histo[0])); + memset(length_histo, 0, sizeof(length_histo)); + InitBlockTypeCodeCalculator(&type_code_calculator); + for (i = 0; i < num_blocks; ++i) { + size_t type_code = NextBlockTypeCode(&type_code_calculator, types[i]); + if (i != 0) ++type_histo[type_code]; + ++length_histo[BlockLengthPrefixCode(lengths[i])]; + } + StoreVarLenUint8(num_types - 1, storage_ix, storage); + if (num_types > 1) { /* TODO(eustas): else? could StoreBlockSwitch occur? */ + BuildAndStoreHuffmanTree(&type_histo[0], num_types + 2, num_types + 2, tree, + &code->type_depths[0], &code->type_bits[0], + storage_ix, storage); + BuildAndStoreHuffmanTree(&length_histo[0], BROTLI_NUM_BLOCK_LEN_SYMBOLS, + BROTLI_NUM_BLOCK_LEN_SYMBOLS, + tree, &code->length_depths[0], + &code->length_bits[0], storage_ix, storage); + StoreBlockSwitch(code, lengths[0], types[0], 1, storage_ix, storage); + } +} + +/* Stores a context map where the histogram type is always the block type. */ +static void StoreTrivialContextMap(EncodeContextMapArena* arena, + size_t num_types, + size_t context_bits, + HuffmanTree* tree, + size_t* storage_ix, + uint8_t* storage) { + StoreVarLenUint8(num_types - 1, storage_ix, storage); + if (num_types > 1) { + size_t repeat_code = context_bits - 1u; + size_t repeat_bits = (1u << repeat_code) - 1u; + size_t alphabet_size = num_types + repeat_code; + uint32_t* BROTLI_RESTRICT const histogram = arena->histogram; + uint8_t* BROTLI_RESTRICT const depths = arena->depths; + uint16_t* BROTLI_RESTRICT const bits = arena->bits; + size_t i; + memset(histogram, 0, alphabet_size * sizeof(histogram[0])); + /* Write RLEMAX. */ + BrotliWriteBits(1, 1, storage_ix, storage); + BrotliWriteBits(4, repeat_code - 1, storage_ix, storage); + histogram[repeat_code] = (uint32_t)num_types; + histogram[0] = 1; + for (i = context_bits; i < alphabet_size; ++i) { + histogram[i] = 1; + } + BuildAndStoreHuffmanTree(histogram, alphabet_size, alphabet_size, + tree, depths, bits, storage_ix, storage); + for (i = 0; i < num_types; ++i) { + size_t code = (i == 0 ? 0 : i + context_bits - 1); + BrotliWriteBits(depths[code], bits[code], storage_ix, storage); + BrotliWriteBits( + depths[repeat_code], bits[repeat_code], storage_ix, storage); + BrotliWriteBits(repeat_code, repeat_bits, storage_ix, storage); + } + /* Write IMTF (inverse-move-to-front) bit. */ + BrotliWriteBits(1, 1, storage_ix, storage); + } +} + +/* Manages the encoding of one block category (literal, command or distance). */ +typedef struct BlockEncoder { + size_t histogram_length_; + size_t num_block_types_; + const uint8_t* block_types_; /* Not owned. */ + const uint32_t* block_lengths_; /* Not owned. */ + size_t num_blocks_; + BlockSplitCode block_split_code_; + size_t block_ix_; + size_t block_len_; + size_t entropy_ix_; + uint8_t* depths_; + uint16_t* bits_; +} BlockEncoder; + +static void InitBlockEncoder(BlockEncoder* self, size_t histogram_length, + size_t num_block_types, const uint8_t* block_types, + const uint32_t* block_lengths, const size_t num_blocks) { + self->histogram_length_ = histogram_length; + self->num_block_types_ = num_block_types; + self->block_types_ = block_types; + self->block_lengths_ = block_lengths; + self->num_blocks_ = num_blocks; + InitBlockTypeCodeCalculator(&self->block_split_code_.type_code_calculator); + self->block_ix_ = 0; + self->block_len_ = num_blocks == 0 ? 0 : block_lengths[0]; + self->entropy_ix_ = 0; + self->depths_ = 0; + self->bits_ = 0; +} + +static void CleanupBlockEncoder(MemoryManager* m, BlockEncoder* self) { + BROTLI_FREE(m, self->depths_); + BROTLI_FREE(m, self->bits_); +} + +/* Creates entropy codes of block lengths and block types and stores them + to the bit stream. */ +static void BuildAndStoreBlockSwitchEntropyCodes(BlockEncoder* self, + HuffmanTree* tree, size_t* storage_ix, uint8_t* storage) { + BuildAndStoreBlockSplitCode(self->block_types_, self->block_lengths_, + self->num_blocks_, self->num_block_types_, tree, &self->block_split_code_, + storage_ix, storage); +} + +/* Stores the next symbol with the entropy code of the current block type. + Updates the block type and block length at block boundaries. */ +static void StoreSymbol(BlockEncoder* self, size_t symbol, size_t* storage_ix, + uint8_t* storage) { + if (self->block_len_ == 0) { + size_t block_ix = ++self->block_ix_; + uint32_t block_len = self->block_lengths_[block_ix]; + uint8_t block_type = self->block_types_[block_ix]; + self->block_len_ = block_len; + self->entropy_ix_ = block_type * self->histogram_length_; + StoreBlockSwitch(&self->block_split_code_, block_len, block_type, 0, + storage_ix, storage); + } + --self->block_len_; + { + size_t ix = self->entropy_ix_ + symbol; + BrotliWriteBits(self->depths_[ix], self->bits_[ix], storage_ix, storage); + } +} + +/* Stores the next symbol with the entropy code of the current block type and + context value. + Updates the block type and block length at block boundaries. */ +static void StoreSymbolWithContext(BlockEncoder* self, size_t symbol, + size_t context, const uint32_t* context_map, size_t* storage_ix, + uint8_t* storage, const size_t context_bits) { + if (self->block_len_ == 0) { + size_t block_ix = ++self->block_ix_; + uint32_t block_len = self->block_lengths_[block_ix]; + uint8_t block_type = self->block_types_[block_ix]; + self->block_len_ = block_len; + self->entropy_ix_ = (size_t)block_type << context_bits; + StoreBlockSwitch(&self->block_split_code_, block_len, block_type, 0, + storage_ix, storage); + } + --self->block_len_; + { + size_t histo_ix = context_map[self->entropy_ix_ + context]; + size_t ix = histo_ix * self->histogram_length_ + symbol; + BrotliWriteBits(self->depths_[ix], self->bits_[ix], storage_ix, storage); + } +} + +#define FN(X) X ## Literal +/* NOLINTNEXTLINE(build/include) */ +#include "block_encoder_inc.h" +#undef FN + +#define FN(X) X ## Command +/* NOLINTNEXTLINE(build/include) */ +#include "block_encoder_inc.h" +#undef FN + +#define FN(X) X ## Distance +/* NOLINTNEXTLINE(build/include) */ +#include "block_encoder_inc.h" +#undef FN + +static void JumpToByteBoundary(size_t* storage_ix, uint8_t* storage) { + *storage_ix = (*storage_ix + 7u) & ~7u; + storage[*storage_ix >> 3] = 0; +} + +typedef struct StoreMetablockArena { + BlockEncoder literal_enc; + BlockEncoder command_enc; + BlockEncoder distance_enc; + EncodeContextMapArena context_map_arena; +} StoreMetablockArena; + +void BrotliStoreMetaBlock(MemoryManager* m, + const uint8_t* input, size_t start_pos, size_t length, size_t mask, + uint8_t prev_byte, uint8_t prev_byte2, BROTLI_BOOL is_last, + const BrotliEncoderParams* params, ContextType literal_context_mode, + const Command* commands, size_t n_commands, const MetaBlockSplit* mb, + size_t* storage_ix, uint8_t* storage) { + + size_t pos = start_pos; + size_t i; + uint32_t num_distance_symbols = params->dist.alphabet_size_max; + uint32_t num_effective_distance_symbols = params->dist.alphabet_size_limit; + HuffmanTree* tree; + ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode); + StoreMetablockArena* arena = NULL; + BlockEncoder* literal_enc = NULL; + BlockEncoder* command_enc = NULL; + BlockEncoder* distance_enc = NULL; + const BrotliDistanceParams* dist = ¶ms->dist; + BROTLI_DCHECK( + num_effective_distance_symbols <= BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS); + + StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage); + + tree = BROTLI_ALLOC(m, HuffmanTree, MAX_HUFFMAN_TREE_SIZE); + arena = BROTLI_ALLOC(m, StoreMetablockArena, 1); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tree) || BROTLI_IS_NULL(arena)) return; + literal_enc = &arena->literal_enc; + command_enc = &arena->command_enc; + distance_enc = &arena->distance_enc; + InitBlockEncoder(literal_enc, BROTLI_NUM_LITERAL_SYMBOLS, + mb->literal_split.num_types, mb->literal_split.types, + mb->literal_split.lengths, mb->literal_split.num_blocks); + InitBlockEncoder(command_enc, BROTLI_NUM_COMMAND_SYMBOLS, + mb->command_split.num_types, mb->command_split.types, + mb->command_split.lengths, mb->command_split.num_blocks); + InitBlockEncoder(distance_enc, num_effective_distance_symbols, + mb->distance_split.num_types, mb->distance_split.types, + mb->distance_split.lengths, mb->distance_split.num_blocks); + + BuildAndStoreBlockSwitchEntropyCodes(literal_enc, tree, storage_ix, storage); + BuildAndStoreBlockSwitchEntropyCodes(command_enc, tree, storage_ix, storage); + BuildAndStoreBlockSwitchEntropyCodes(distance_enc, tree, storage_ix, storage); + + BrotliWriteBits(2, dist->distance_postfix_bits, storage_ix, storage); + BrotliWriteBits( + 4, dist->num_direct_distance_codes >> dist->distance_postfix_bits, + storage_ix, storage); + for (i = 0; i < mb->literal_split.num_types; ++i) { + BrotliWriteBits(2, literal_context_mode, storage_ix, storage); + } + + if (mb->literal_context_map_size == 0) { + StoreTrivialContextMap( + &arena->context_map_arena, mb->literal_histograms_size, + BROTLI_LITERAL_CONTEXT_BITS, tree, storage_ix, storage); + } else { + EncodeContextMap(m, &arena->context_map_arena, + mb->literal_context_map, mb->literal_context_map_size, + mb->literal_histograms_size, tree, storage_ix, storage); + if (BROTLI_IS_OOM(m)) return; + } + + if (mb->distance_context_map_size == 0) { + StoreTrivialContextMap( + &arena->context_map_arena, mb->distance_histograms_size, + BROTLI_DISTANCE_CONTEXT_BITS, tree, storage_ix, storage); + } else { + EncodeContextMap(m, &arena->context_map_arena, + mb->distance_context_map, mb->distance_context_map_size, + mb->distance_histograms_size, tree, storage_ix, storage); + if (BROTLI_IS_OOM(m)) return; + } + + BuildAndStoreEntropyCodesLiteral(m, literal_enc, mb->literal_histograms, + mb->literal_histograms_size, BROTLI_NUM_LITERAL_SYMBOLS, tree, + storage_ix, storage); + if (BROTLI_IS_OOM(m)) return; + BuildAndStoreEntropyCodesCommand(m, command_enc, mb->command_histograms, + mb->command_histograms_size, BROTLI_NUM_COMMAND_SYMBOLS, tree, + storage_ix, storage); + if (BROTLI_IS_OOM(m)) return; + BuildAndStoreEntropyCodesDistance(m, distance_enc, mb->distance_histograms, + mb->distance_histograms_size, num_distance_symbols, tree, + storage_ix, storage); + if (BROTLI_IS_OOM(m)) return; + BROTLI_FREE(m, tree); + + for (i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + size_t cmd_code = cmd.cmd_prefix_; + StoreSymbol(command_enc, cmd_code, storage_ix, storage); + StoreCommandExtra(&cmd, storage_ix, storage); + if (mb->literal_context_map_size == 0) { + size_t j; + for (j = cmd.insert_len_; j != 0; --j) { + StoreSymbol(literal_enc, input[pos & mask], storage_ix, storage); + ++pos; + } + } else { + size_t j; + for (j = cmd.insert_len_; j != 0; --j) { + size_t context = + BROTLI_CONTEXT(prev_byte, prev_byte2, literal_context_lut); + uint8_t literal = input[pos & mask]; + StoreSymbolWithContext(literal_enc, literal, context, + mb->literal_context_map, storage_ix, storage, + BROTLI_LITERAL_CONTEXT_BITS); + prev_byte2 = prev_byte; + prev_byte = literal; + ++pos; + } + } + pos += CommandCopyLen(&cmd); + if (CommandCopyLen(&cmd)) { + prev_byte2 = input[(pos - 2) & mask]; + prev_byte = input[(pos - 1) & mask]; + if (cmd.cmd_prefix_ >= 128) { + size_t dist_code = cmd.dist_prefix_ & 0x3FF; + uint32_t distnumextra = cmd.dist_prefix_ >> 10; + uint64_t distextra = cmd.dist_extra_; + if (mb->distance_context_map_size == 0) { + StoreSymbol(distance_enc, dist_code, storage_ix, storage); + } else { + size_t context = CommandDistanceContext(&cmd); + StoreSymbolWithContext(distance_enc, dist_code, context, + mb->distance_context_map, storage_ix, storage, + BROTLI_DISTANCE_CONTEXT_BITS); + } + BrotliWriteBits(distnumextra, distextra, storage_ix, storage); + } + } + } + CleanupBlockEncoder(m, distance_enc); + CleanupBlockEncoder(m, command_enc); + CleanupBlockEncoder(m, literal_enc); + BROTLI_FREE(m, arena); + if (is_last) { + JumpToByteBoundary(storage_ix, storage); + } +} + +static void BuildHistograms(const uint8_t* input, + size_t start_pos, + size_t mask, + const Command* commands, + size_t n_commands, + HistogramLiteral* lit_histo, + HistogramCommand* cmd_histo, + HistogramDistance* dist_histo) { + size_t pos = start_pos; + size_t i; + for (i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + size_t j; + HistogramAddCommand(cmd_histo, cmd.cmd_prefix_); + for (j = cmd.insert_len_; j != 0; --j) { + HistogramAddLiteral(lit_histo, input[pos & mask]); + ++pos; + } + pos += CommandCopyLen(&cmd); + if (CommandCopyLen(&cmd) && cmd.cmd_prefix_ >= 128) { + HistogramAddDistance(dist_histo, cmd.dist_prefix_ & 0x3FF); + } + } +} + +static void StoreDataWithHuffmanCodes(const uint8_t* input, + size_t start_pos, + size_t mask, + const Command* commands, + size_t n_commands, + const uint8_t* lit_depth, + const uint16_t* lit_bits, + const uint8_t* cmd_depth, + const uint16_t* cmd_bits, + const uint8_t* dist_depth, + const uint16_t* dist_bits, + size_t* storage_ix, + uint8_t* storage) { + size_t pos = start_pos; + size_t i; + for (i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + const size_t cmd_code = cmd.cmd_prefix_; + size_t j; + BrotliWriteBits( + cmd_depth[cmd_code], cmd_bits[cmd_code], storage_ix, storage); + StoreCommandExtra(&cmd, storage_ix, storage); + for (j = cmd.insert_len_; j != 0; --j) { + const uint8_t literal = input[pos & mask]; + BrotliWriteBits( + lit_depth[literal], lit_bits[literal], storage_ix, storage); + ++pos; + } + pos += CommandCopyLen(&cmd); + if (CommandCopyLen(&cmd) && cmd.cmd_prefix_ >= 128) { + const size_t dist_code = cmd.dist_prefix_ & 0x3FF; + const uint32_t distnumextra = cmd.dist_prefix_ >> 10; + const uint32_t distextra = cmd.dist_extra_; + BrotliWriteBits(dist_depth[dist_code], dist_bits[dist_code], + storage_ix, storage); + BrotliWriteBits(distnumextra, distextra, storage_ix, storage); + } + } +} + +/* TODO(eustas): pull alloc/dealloc to caller? */ +typedef struct MetablockArena { + HistogramLiteral lit_histo; + HistogramCommand cmd_histo; + HistogramDistance dist_histo; + /* TODO(eustas): merge bits and depth? */ + uint8_t lit_depth[BROTLI_NUM_LITERAL_SYMBOLS]; + uint16_t lit_bits[BROTLI_NUM_LITERAL_SYMBOLS]; + uint8_t cmd_depth[BROTLI_NUM_COMMAND_SYMBOLS]; + uint16_t cmd_bits[BROTLI_NUM_COMMAND_SYMBOLS]; + uint8_t dist_depth[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE]; + uint16_t dist_bits[MAX_SIMPLE_DISTANCE_ALPHABET_SIZE]; + HuffmanTree tree[MAX_HUFFMAN_TREE_SIZE]; +} MetablockArena; + +void BrotliStoreMetaBlockTrivial(MemoryManager* m, + const uint8_t* input, size_t start_pos, size_t length, size_t mask, + BROTLI_BOOL is_last, const BrotliEncoderParams* params, + const Command* commands, size_t n_commands, + size_t* storage_ix, uint8_t* storage) { + MetablockArena* arena = BROTLI_ALLOC(m, MetablockArena, 1); + uint32_t num_distance_symbols = params->dist.alphabet_size_max; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(arena)) return; + + StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage); + + HistogramClearLiteral(&arena->lit_histo); + HistogramClearCommand(&arena->cmd_histo); + HistogramClearDistance(&arena->dist_histo); + + BuildHistograms(input, start_pos, mask, commands, n_commands, + &arena->lit_histo, &arena->cmd_histo, &arena->dist_histo); + + BrotliWriteBits(13, 0, storage_ix, storage); + + BuildAndStoreHuffmanTree(arena->lit_histo.data_, BROTLI_NUM_LITERAL_SYMBOLS, + BROTLI_NUM_LITERAL_SYMBOLS, arena->tree, + arena->lit_depth, arena->lit_bits, + storage_ix, storage); + BuildAndStoreHuffmanTree(arena->cmd_histo.data_, BROTLI_NUM_COMMAND_SYMBOLS, + BROTLI_NUM_COMMAND_SYMBOLS, arena->tree, + arena->cmd_depth, arena->cmd_bits, + storage_ix, storage); + BuildAndStoreHuffmanTree(arena->dist_histo.data_, + MAX_SIMPLE_DISTANCE_ALPHABET_SIZE, + num_distance_symbols, arena->tree, + arena->dist_depth, arena->dist_bits, + storage_ix, storage); + StoreDataWithHuffmanCodes(input, start_pos, mask, commands, + n_commands, arena->lit_depth, arena->lit_bits, + arena->cmd_depth, arena->cmd_bits, + arena->dist_depth, arena->dist_bits, + storage_ix, storage); + BROTLI_FREE(m, arena); + if (is_last) { + JumpToByteBoundary(storage_ix, storage); + } +} + +void BrotliStoreMetaBlockFast(MemoryManager* m, + const uint8_t* input, size_t start_pos, size_t length, size_t mask, + BROTLI_BOOL is_last, const BrotliEncoderParams* params, + const Command* commands, size_t n_commands, + size_t* storage_ix, uint8_t* storage) { + MetablockArena* arena = BROTLI_ALLOC(m, MetablockArena, 1); + uint32_t num_distance_symbols = params->dist.alphabet_size_max; + uint32_t distance_alphabet_bits = + Log2FloorNonZero(num_distance_symbols - 1) + 1; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(arena)) return; + + StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage); + + BrotliWriteBits(13, 0, storage_ix, storage); + + if (n_commands <= 128) { + uint32_t histogram[BROTLI_NUM_LITERAL_SYMBOLS] = { 0 }; + size_t pos = start_pos; + size_t num_literals = 0; + size_t i; + for (i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + size_t j; + for (j = cmd.insert_len_; j != 0; --j) { + ++histogram[input[pos & mask]]; + ++pos; + } + num_literals += cmd.insert_len_; + pos += CommandCopyLen(&cmd); + } + BrotliBuildAndStoreHuffmanTreeFast(arena->tree, histogram, num_literals, + /* max_bits = */ 8, + arena->lit_depth, arena->lit_bits, + storage_ix, storage); + StoreStaticCommandHuffmanTree(storage_ix, storage); + StoreStaticDistanceHuffmanTree(storage_ix, storage); + StoreDataWithHuffmanCodes(input, start_pos, mask, commands, + n_commands, arena->lit_depth, arena->lit_bits, + kStaticCommandCodeDepth, + kStaticCommandCodeBits, + kStaticDistanceCodeDepth, + kStaticDistanceCodeBits, + storage_ix, storage); + } else { + HistogramClearLiteral(&arena->lit_histo); + HistogramClearCommand(&arena->cmd_histo); + HistogramClearDistance(&arena->dist_histo); + BuildHistograms(input, start_pos, mask, commands, n_commands, + &arena->lit_histo, &arena->cmd_histo, &arena->dist_histo); + BrotliBuildAndStoreHuffmanTreeFast(arena->tree, arena->lit_histo.data_, + arena->lit_histo.total_count_, + /* max_bits = */ 8, + arena->lit_depth, arena->lit_bits, + storage_ix, storage); + BrotliBuildAndStoreHuffmanTreeFast(arena->tree, arena->cmd_histo.data_, + arena->cmd_histo.total_count_, + /* max_bits = */ 10, + arena->cmd_depth, arena->cmd_bits, + storage_ix, storage); + BrotliBuildAndStoreHuffmanTreeFast(arena->tree, arena->dist_histo.data_, + arena->dist_histo.total_count_, + /* max_bits = */ + distance_alphabet_bits, + arena->dist_depth, arena->dist_bits, + storage_ix, storage); + StoreDataWithHuffmanCodes(input, start_pos, mask, commands, + n_commands, arena->lit_depth, arena->lit_bits, + arena->cmd_depth, arena->cmd_bits, + arena->dist_depth, arena->dist_bits, + storage_ix, storage); + } + + BROTLI_FREE(m, arena); + + if (is_last) { + JumpToByteBoundary(storage_ix, storage); + } +} + +/* This is for storing uncompressed blocks (simple raw storage of + bytes-as-bytes). */ +void BrotliStoreUncompressedMetaBlock(BROTLI_BOOL is_final_block, + const uint8_t* BROTLI_RESTRICT input, + size_t position, size_t mask, + size_t len, + size_t* BROTLI_RESTRICT storage_ix, + uint8_t* BROTLI_RESTRICT storage) { + size_t masked_pos = position & mask; + BrotliStoreUncompressedMetaBlockHeader(len, storage_ix, storage); + JumpToByteBoundary(storage_ix, storage); + + if (masked_pos + len > mask + 1) { + size_t len1 = mask + 1 - masked_pos; + memcpy(&storage[*storage_ix >> 3], &input[masked_pos], len1); + *storage_ix += len1 << 3; + len -= len1; + masked_pos = 0; + } + memcpy(&storage[*storage_ix >> 3], &input[masked_pos], len); + *storage_ix += len << 3; + + /* We need to clear the next 4 bytes to continue to be + compatible with BrotliWriteBits. */ + BrotliWriteBitsPrepareStorage(*storage_ix, storage); + + /* Since the uncompressed block itself may not be the final block, add an + empty one after this. */ + if (is_final_block) { + BrotliWriteBits(1, 1, storage_ix, storage); /* islast */ + BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */ + JumpToByteBoundary(storage_ix, storage); + } +} + +#if defined(BROTLI_TEST) +void BrotliGetBlockLengthPrefixCodeForTest(uint32_t len, size_t* code, + uint32_t* n_extra, uint32_t* extra); +void BrotliGetBlockLengthPrefixCodeForTest(uint32_t len, size_t* code, + uint32_t* n_extra, uint32_t* extra) { + GetBlockLengthPrefixCode(len, code, n_extra, extra); +} +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/brotli_bit_stream.h b/packages/runtime/vendor/brotli/c/enc/brotli_bit_stream.h new file mode 100644 index 000000000..7b72bdcee --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/brotli_bit_stream.h @@ -0,0 +1,83 @@ +/* Copyright 2014 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions to convert brotli-related data structures into the + brotli bit stream. The functions here operate under + assumption that there is enough space in the storage, i.e., there are + no out-of-range checks anywhere. + + These functions do bit addressing into a byte array. The byte array + is called "storage" and the index to the bit is called storage_ix + in function arguments. */ + +#ifndef BROTLI_ENC_BROTLI_BIT_STREAM_H_ +#define BROTLI_ENC_BROTLI_BIT_STREAM_H_ + +#include "../common/context.h" +#include "../common/platform.h" +#include "command.h" +#include "entropy_encode.h" +#include "memory.h" +#include "metablock.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* All Store functions here will use a storage_ix, which is always the bit + position for the current storage. */ + +BROTLI_INTERNAL void BrotliStoreHuffmanTree(const uint8_t* depths, size_t num, + HuffmanTree* tree, size_t* storage_ix, uint8_t* storage); + +BROTLI_INTERNAL void BrotliBuildAndStoreHuffmanTreeFast( + HuffmanTree* tree, const uint32_t* histogram, const size_t histogram_total, + const size_t max_bits, uint8_t* depth, uint16_t* bits, size_t* storage_ix, + uint8_t* storage); + +/* REQUIRES: length > 0 */ +/* REQUIRES: length <= (1 << 24) */ +BROTLI_INTERNAL void BrotliStoreMetaBlock(MemoryManager* m, + const uint8_t* input, size_t start_pos, size_t length, size_t mask, + uint8_t prev_byte, uint8_t prev_byte2, BROTLI_BOOL is_last, + const BrotliEncoderParams* params, ContextType literal_context_mode, + const Command* commands, size_t n_commands, const MetaBlockSplit* mb, + size_t* storage_ix, uint8_t* storage); + +/* Stores the meta-block without doing any block splitting, just collects + one histogram per block category and uses that for entropy coding. + REQUIRES: length > 0 + REQUIRES: length <= (1 << 24) */ +BROTLI_INTERNAL void BrotliStoreMetaBlockTrivial(MemoryManager* m, + const uint8_t* input, size_t start_pos, size_t length, size_t mask, + BROTLI_BOOL is_last, const BrotliEncoderParams* params, + const Command* commands, size_t n_commands, + size_t* storage_ix, uint8_t* storage); + +/* Same as above, but uses static prefix codes for histograms with a only a few + symbols, and uses static code length prefix codes for all other histograms. + REQUIRES: length > 0 + REQUIRES: length <= (1 << 24) */ +BROTLI_INTERNAL void BrotliStoreMetaBlockFast(MemoryManager* m, + const uint8_t* input, size_t start_pos, size_t length, size_t mask, + BROTLI_BOOL is_last, const BrotliEncoderParams* params, + const Command* commands, size_t n_commands, + size_t* storage_ix, uint8_t* storage); + +/* This is for storing uncompressed blocks (simple raw storage of + bytes-as-bytes). + REQUIRES: length > 0 + REQUIRES: length <= (1 << 24) */ +BROTLI_INTERNAL void BrotliStoreUncompressedMetaBlock( + BROTLI_BOOL is_final_block, const uint8_t* BROTLI_RESTRICT input, + size_t position, size_t mask, size_t len, + size_t* BROTLI_RESTRICT storage_ix, uint8_t* BROTLI_RESTRICT storage); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_BROTLI_BIT_STREAM_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/cluster.c b/packages/runtime/vendor/brotli/c/enc/cluster.c new file mode 100644 index 000000000..4bf94ab76 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/cluster.c @@ -0,0 +1,55 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions for clustering similar histograms together. */ + +#include "cluster.h" + +#include "../common/platform.h" +#include "bit_cost.h" /* BrotliPopulationCost */ +#include "fast_log.h" +#include "histogram.h" +#include "memory.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static BROTLI_INLINE BROTLI_BOOL HistogramPairIsLess( + const HistogramPair* p1, const HistogramPair* p2) { + if (p1->cost_diff != p2->cost_diff) { + return TO_BROTLI_BOOL(p1->cost_diff > p2->cost_diff); + } + return TO_BROTLI_BOOL((p1->idx2 - p1->idx1) > (p2->idx2 - p2->idx1)); +} + +/* Returns entropy reduction of the context map when we combine two clusters. */ +static BROTLI_INLINE double ClusterCostDiff(size_t size_a, size_t size_b) { + size_t size_c = size_a + size_b; + return (double)size_a * FastLog2(size_a) + + (double)size_b * FastLog2(size_b) - + (double)size_c * FastLog2(size_c); +} + +#define CODE(X) X + +#define FN(X) X ## Literal +#include "cluster_inc.h" /* NOLINT(build/include) */ +#undef FN + +#define FN(X) X ## Command +#include "cluster_inc.h" /* NOLINT(build/include) */ +#undef FN + +#define FN(X) X ## Distance +#include "cluster_inc.h" /* NOLINT(build/include) */ +#undef FN + +#undef CODE + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/cluster.h b/packages/runtime/vendor/brotli/c/enc/cluster.h new file mode 100644 index 000000000..6519116c4 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/cluster.h @@ -0,0 +1,47 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions for clustering similar histograms together. */ + +#ifndef BROTLI_ENC_CLUSTER_H_ +#define BROTLI_ENC_CLUSTER_H_ + +#include "../common/platform.h" +#include "histogram.h" +#include "memory.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct HistogramPair { + uint32_t idx1; + uint32_t idx2; + double cost_combo; + double cost_diff; +} HistogramPair; + +#define CODE(X) /* Declaration */; + +#define FN(X) X ## Literal +#include "cluster_inc.h" /* NOLINT(build/include) */ +#undef FN + +#define FN(X) X ## Command +#include "cluster_inc.h" /* NOLINT(build/include) */ +#undef FN + +#define FN(X) X ## Distance +#include "cluster_inc.h" /* NOLINT(build/include) */ +#undef FN + +#undef CODE + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_CLUSTER_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/cluster_inc.h b/packages/runtime/vendor/brotli/c/enc/cluster_inc.h new file mode 100644 index 000000000..d6215ef06 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/cluster_inc.h @@ -0,0 +1,325 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN, CODE */ + +#define HistogramType FN(Histogram) + +/* Computes the bit cost reduction by combining out[idx1] and out[idx2] and if + it is below a threshold, stores the pair (idx1, idx2) in the *pairs queue. */ +BROTLI_INTERNAL void FN(BrotliCompareAndPushToQueue)( + const HistogramType* out, HistogramType* tmp, const uint32_t* cluster_size, + uint32_t idx1, uint32_t idx2, size_t max_num_pairs, HistogramPair* pairs, + size_t* num_pairs) CODE({ + BROTLI_BOOL is_good_pair = BROTLI_FALSE; + HistogramPair p; + p.idx1 = p.idx2 = 0; + p.cost_diff = p.cost_combo = 0; + if (idx1 == idx2) { + return; + } + if (idx2 < idx1) { + uint32_t t = idx2; + idx2 = idx1; + idx1 = t; + } + p.idx1 = idx1; + p.idx2 = idx2; + p.cost_diff = 0.5 * ClusterCostDiff(cluster_size[idx1], cluster_size[idx2]); + p.cost_diff -= out[idx1].bit_cost_; + p.cost_diff -= out[idx2].bit_cost_; + + if (out[idx1].total_count_ == 0) { + p.cost_combo = out[idx2].bit_cost_; + is_good_pair = BROTLI_TRUE; + } else if (out[idx2].total_count_ == 0) { + p.cost_combo = out[idx1].bit_cost_; + is_good_pair = BROTLI_TRUE; + } else { + double threshold = *num_pairs == 0 ? 1e99 : + BROTLI_MAX(double, 0.0, pairs[0].cost_diff); + double cost_combo; + *tmp = out[idx1]; + FN(HistogramAddHistogram)(tmp, &out[idx2]); + cost_combo = FN(BrotliPopulationCost)(tmp); + if (cost_combo < threshold - p.cost_diff) { + p.cost_combo = cost_combo; + is_good_pair = BROTLI_TRUE; + } + } + if (is_good_pair) { + p.cost_diff += p.cost_combo; + if (*num_pairs > 0 && HistogramPairIsLess(&pairs[0], &p)) { + /* Replace the top of the queue if needed. */ + if (*num_pairs < max_num_pairs) { + pairs[*num_pairs] = pairs[0]; + ++(*num_pairs); + } + pairs[0] = p; + } else if (*num_pairs < max_num_pairs) { + pairs[*num_pairs] = p; + ++(*num_pairs); + } + } +}) + +BROTLI_INTERNAL size_t FN(BrotliHistogramCombine)(HistogramType* out, + HistogramType* tmp, + uint32_t* cluster_size, + uint32_t* symbols, + uint32_t* clusters, + HistogramPair* pairs, + size_t num_clusters, + size_t symbols_size, + size_t max_clusters, + size_t max_num_pairs) CODE({ + double cost_diff_threshold = 0.0; + size_t min_cluster_size = 1; + size_t num_pairs = 0; + + { + /* We maintain a vector of histogram pairs, with the property that the pair + with the maximum bit cost reduction is the first. */ + size_t idx1; + for (idx1 = 0; idx1 < num_clusters; ++idx1) { + size_t idx2; + for (idx2 = idx1 + 1; idx2 < num_clusters; ++idx2) { + FN(BrotliCompareAndPushToQueue)(out, tmp, cluster_size, clusters[idx1], + clusters[idx2], max_num_pairs, &pairs[0], &num_pairs); + } + } + } + + while (num_clusters > min_cluster_size) { + uint32_t best_idx1; + uint32_t best_idx2; + size_t i; + if (pairs[0].cost_diff >= cost_diff_threshold) { + cost_diff_threshold = 1e99; + min_cluster_size = max_clusters; + continue; + } + /* Take the best pair from the top of heap. */ + best_idx1 = pairs[0].idx1; + best_idx2 = pairs[0].idx2; + FN(HistogramAddHistogram)(&out[best_idx1], &out[best_idx2]); + out[best_idx1].bit_cost_ = pairs[0].cost_combo; + cluster_size[best_idx1] += cluster_size[best_idx2]; + for (i = 0; i < symbols_size; ++i) { + if (symbols[i] == best_idx2) { + symbols[i] = best_idx1; + } + } + for (i = 0; i < num_clusters; ++i) { + if (clusters[i] == best_idx2) { + memmove(&clusters[i], &clusters[i + 1], + (num_clusters - i - 1) * sizeof(clusters[0])); + break; + } + } + --num_clusters; + { + /* Remove pairs intersecting the just combined best pair. */ + size_t copy_to_idx = 0; + for (i = 0; i < num_pairs; ++i) { + HistogramPair* p = &pairs[i]; + if (p->idx1 == best_idx1 || p->idx2 == best_idx1 || + p->idx1 == best_idx2 || p->idx2 == best_idx2) { + /* Remove invalid pair from the queue. */ + continue; + } + if (HistogramPairIsLess(&pairs[0], p)) { + /* Replace the top of the queue if needed. */ + HistogramPair front = pairs[0]; + pairs[0] = *p; + pairs[copy_to_idx] = front; + } else { + pairs[copy_to_idx] = *p; + } + ++copy_to_idx; + } + num_pairs = copy_to_idx; + } + + /* Push new pairs formed with the combined histogram to the heap. */ + for (i = 0; i < num_clusters; ++i) { + FN(BrotliCompareAndPushToQueue)(out, tmp, cluster_size, best_idx1, + clusters[i], max_num_pairs, &pairs[0], &num_pairs); + } + } + return num_clusters; +}) + +/* What is the bit cost of moving histogram from cur_symbol to candidate. */ +BROTLI_INTERNAL double FN(BrotliHistogramBitCostDistance)( + const HistogramType* histogram, const HistogramType* candidate, + HistogramType* tmp) CODE({ + if (histogram->total_count_ == 0) { + return 0.0; + } else { + *tmp = *histogram; + FN(HistogramAddHistogram)(tmp, candidate); + return FN(BrotliPopulationCost)(tmp) - candidate->bit_cost_; + } +}) + +/* Find the best 'out' histogram for each of the 'in' histograms. + When called, clusters[0..num_clusters) contains the unique values from + symbols[0..in_size), but this property is not preserved in this function. + Note: we assume that out[]->bit_cost_ is already up-to-date. */ +BROTLI_INTERNAL void FN(BrotliHistogramRemap)(const HistogramType* in, + size_t in_size, const uint32_t* clusters, size_t num_clusters, + HistogramType* out, HistogramType* tmp, uint32_t* symbols) CODE({ + size_t i; + for (i = 0; i < in_size; ++i) { + uint32_t best_out = i == 0 ? symbols[0] : symbols[i - 1]; + double best_bits = + FN(BrotliHistogramBitCostDistance)(&in[i], &out[best_out], tmp); + size_t j; + for (j = 0; j < num_clusters; ++j) { + const double cur_bits = + FN(BrotliHistogramBitCostDistance)(&in[i], &out[clusters[j]], tmp); + if (cur_bits < best_bits) { + best_bits = cur_bits; + best_out = clusters[j]; + } + } + symbols[i] = best_out; + } + + /* Recompute each out based on raw and symbols. */ + for (i = 0; i < num_clusters; ++i) { + FN(HistogramClear)(&out[clusters[i]]); + } + for (i = 0; i < in_size; ++i) { + FN(HistogramAddHistogram)(&out[symbols[i]], &in[i]); + } +}) + +/* Reorders elements of the out[0..length) array and changes values in + symbols[0..length) array in the following way: + * when called, symbols[] contains indexes into out[], and has N unique + values (possibly N < length) + * on return, symbols'[i] = f(symbols[i]) and + out'[symbols'[i]] = out[symbols[i]], for each 0 <= i < length, + where f is a bijection between the range of symbols[] and [0..N), and + the first occurrences of values in symbols'[i] come in consecutive + increasing order. + Returns N, the number of unique values in symbols[]. */ +BROTLI_INTERNAL size_t FN(BrotliHistogramReindex)(MemoryManager* m, + HistogramType* out, uint32_t* symbols, size_t length) CODE({ + static const uint32_t kInvalidIndex = BROTLI_UINT32_MAX; + uint32_t* new_index = BROTLI_ALLOC(m, uint32_t, length); + uint32_t next_index; + HistogramType* tmp; + size_t i; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_index)) return 0; + for (i = 0; i < length; ++i) { + new_index[i] = kInvalidIndex; + } + next_index = 0; + for (i = 0; i < length; ++i) { + if (new_index[symbols[i]] == kInvalidIndex) { + new_index[symbols[i]] = next_index; + ++next_index; + } + } + /* TODO(eustas): by using idea of "cycle-sort" we can avoid allocation of + tmp and reduce the number of copying by the factor of 2. */ + tmp = BROTLI_ALLOC(m, HistogramType, next_index); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tmp)) return 0; + next_index = 0; + for (i = 0; i < length; ++i) { + if (new_index[symbols[i]] == next_index) { + tmp[next_index] = out[symbols[i]]; + ++next_index; + } + symbols[i] = new_index[symbols[i]]; + } + BROTLI_FREE(m, new_index); + for (i = 0; i < next_index; ++i) { + out[i] = tmp[i]; + } + BROTLI_FREE(m, tmp); + return next_index; +}) + +BROTLI_INTERNAL void FN(BrotliClusterHistograms)( + MemoryManager* m, const HistogramType* in, const size_t in_size, + size_t max_histograms, HistogramType* out, size_t* out_size, + uint32_t* histogram_symbols) CODE({ + uint32_t* cluster_size = BROTLI_ALLOC(m, uint32_t, in_size); + uint32_t* clusters = BROTLI_ALLOC(m, uint32_t, in_size); + size_t num_clusters = 0; + const size_t max_input_histograms = 64; + size_t pairs_capacity = max_input_histograms * max_input_histograms / 2; + /* For the first pass of clustering, we allow all pairs. */ + HistogramPair* pairs = BROTLI_ALLOC(m, HistogramPair, pairs_capacity + 1); + /* TODO(eustas): move to "persistent" arena? */ + HistogramType* tmp = BROTLI_ALLOC(m, HistogramType, 1); + size_t i; + + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(cluster_size) || + BROTLI_IS_NULL(clusters) || BROTLI_IS_NULL(pairs)|| BROTLI_IS_NULL(tmp)) { + return; + } + + for (i = 0; i < in_size; ++i) { + cluster_size[i] = 1; + } + + for (i = 0; i < in_size; ++i) { + out[i] = in[i]; + out[i].bit_cost_ = FN(BrotliPopulationCost)(&in[i]); + histogram_symbols[i] = (uint32_t)i; + } + + for (i = 0; i < in_size; i += max_input_histograms) { + size_t num_to_combine = + BROTLI_MIN(size_t, in_size - i, max_input_histograms); + size_t num_new_clusters; + size_t j; + for (j = 0; j < num_to_combine; ++j) { + clusters[num_clusters + j] = (uint32_t)(i + j); + } + num_new_clusters = + FN(BrotliHistogramCombine)(out, tmp, cluster_size, + &histogram_symbols[i], + &clusters[num_clusters], pairs, + num_to_combine, num_to_combine, + max_histograms, pairs_capacity); + num_clusters += num_new_clusters; + } + + { + /* For the second pass, we limit the total number of histogram pairs. + After this limit is reached, we only keep searching for the best pair. */ + size_t max_num_pairs = BROTLI_MIN(size_t, + 64 * num_clusters, (num_clusters / 2) * num_clusters); + BROTLI_ENSURE_CAPACITY( + m, HistogramPair, pairs, pairs_capacity, max_num_pairs + 1); + if (BROTLI_IS_OOM(m)) return; + + /* Collapse similar histograms. */ + num_clusters = FN(BrotliHistogramCombine)(out, tmp, cluster_size, + histogram_symbols, clusters, + pairs, num_clusters, in_size, + max_histograms, max_num_pairs); + } + BROTLI_FREE(m, pairs); + BROTLI_FREE(m, cluster_size); + /* Find the optimal map from original histograms to the final ones. */ + FN(BrotliHistogramRemap)(in, in_size, clusters, num_clusters, + out, tmp, histogram_symbols); + BROTLI_FREE(m, tmp); + BROTLI_FREE(m, clusters); + /* Convert the context map to a canonical form. */ + *out_size = FN(BrotliHistogramReindex)(m, out, histogram_symbols, in_size); + if (BROTLI_IS_OOM(m)) return; +}) + +#undef HistogramType diff --git a/packages/runtime/vendor/brotli/c/enc/command.c b/packages/runtime/vendor/brotli/c/enc/command.c new file mode 100644 index 000000000..699fa8098 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/command.c @@ -0,0 +1,28 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "command.h" + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +const uint32_t kBrotliInsBase[BROTLI_NUM_INS_COPY_CODES] = { + 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, + 34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594}; +const uint32_t kBrotliInsExtra[BROTLI_NUM_INS_COPY_CODES] = { + 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 12, 14, 24}; +const uint32_t kBrotliCopyBase[BROTLI_NUM_INS_COPY_CODES] = { + 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, + 22, 30, 38, 54, 70, 102, 134, 198, 326, 582, 1094, 2118}; +const uint32_t kBrotliCopyExtra[BROTLI_NUM_INS_COPY_CODES] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24}; + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/command.h b/packages/runtime/vendor/brotli/c/enc/command.h new file mode 100644 index 000000000..c1cb208e6 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/command.h @@ -0,0 +1,189 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* This class models a sequence of literals and a backward reference copy. */ + +#ifndef BROTLI_ENC_COMMAND_H_ +#define BROTLI_ENC_COMMAND_H_ + +#include "../common/constants.h" +#include "../common/platform.h" +#include "fast_log.h" +#include "params.h" +#include "prefix.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +BROTLI_INTERNAL extern const BROTLI_MODEL("small") +uint32_t kBrotliInsBase[BROTLI_NUM_INS_COPY_CODES]; +BROTLI_INTERNAL extern const BROTLI_MODEL("small") +uint32_t kBrotliInsExtra[BROTLI_NUM_INS_COPY_CODES]; +BROTLI_INTERNAL extern const BROTLI_MODEL("small") +uint32_t kBrotliCopyBase[BROTLI_NUM_INS_COPY_CODES]; +BROTLI_INTERNAL extern const BROTLI_MODEL("small") +uint32_t kBrotliCopyExtra[BROTLI_NUM_INS_COPY_CODES]; + +static BROTLI_INLINE uint16_t GetInsertLengthCode(size_t insertlen) { + if (insertlen < 6) { + return (uint16_t)insertlen; + } else if (insertlen < 130) { + uint32_t nbits = Log2FloorNonZero(insertlen - 2) - 1u; + return (uint16_t)((nbits << 1) + ((insertlen - 2) >> nbits) + 2); + } else if (insertlen < 2114) { + return (uint16_t)(Log2FloorNonZero(insertlen - 66) + 10); + } else if (insertlen < 6210) { + return 21u; + } else if (insertlen < 22594) { + return 22u; + } else { + return 23u; + } +} + +static BROTLI_INLINE uint16_t GetCopyLengthCode(size_t copylen) { + if (copylen < 10) { + return (uint16_t)(copylen - 2); + } else if (copylen < 134) { + uint32_t nbits = Log2FloorNonZero(copylen - 6) - 1u; + return (uint16_t)((nbits << 1) + ((copylen - 6) >> nbits) + 4); + } else if (copylen < 2118) { + return (uint16_t)(Log2FloorNonZero(copylen - 70) + 12); + } else { + return 23u; + } +} + +static BROTLI_INLINE uint16_t CombineLengthCodes( + uint16_t inscode, uint16_t copycode, BROTLI_BOOL use_last_distance) { + uint16_t bits64 = + (uint16_t)((copycode & 0x7u) | ((inscode & 0x7u) << 3u)); + if (use_last_distance && inscode < 8u && copycode < 16u) { + return (copycode < 8u) ? bits64 : (bits64 | 64u); + } else { + /* Specification: 5 Encoding of ... (last table) */ + /* offset = 2 * index, where index is in range [0..8] */ + uint32_t offset = 2u * ((copycode >> 3u) + 3u * (inscode >> 3u)); + /* All values in specification are K * 64, + where K = [2, 3, 6, 4, 5, 8, 7, 9, 10], + i + 1 = [1, 2, 3, 4, 5, 6, 7, 8, 9], + K - i - 1 = [1, 1, 3, 0, 0, 2, 0, 1, 2] = D. + All values in D require only 2 bits to encode. + Magic constant is shifted 6 bits left, to avoid final multiplication. */ + offset = (offset << 5u) + 0x40u + ((0x520D40u >> offset) & 0xC0u); + return (uint16_t)(offset | bits64); + } +} + +static BROTLI_INLINE void GetLengthCode(size_t insertlen, size_t copylen, + BROTLI_BOOL use_last_distance, + uint16_t* code) { + uint16_t inscode = GetInsertLengthCode(insertlen); + uint16_t copycode = GetCopyLengthCode(copylen); + *code = CombineLengthCodes(inscode, copycode, use_last_distance); +} + +static BROTLI_INLINE uint32_t GetInsertBase(uint16_t inscode) { + return kBrotliInsBase[inscode]; +} + +static BROTLI_INLINE uint32_t GetInsertExtra(uint16_t inscode) { + return kBrotliInsExtra[inscode]; +} + +static BROTLI_INLINE uint32_t GetCopyBase(uint16_t copycode) { + return kBrotliCopyBase[copycode]; +} + +static BROTLI_INLINE uint32_t GetCopyExtra(uint16_t copycode) { + return kBrotliCopyExtra[copycode]; +} + +typedef struct Command { + uint32_t insert_len_; + /* Stores copy_len in low 25 bits and copy_code - copy_len in high 7 bit. */ + uint32_t copy_len_; + /* Stores distance extra bits. */ + uint32_t dist_extra_; + uint16_t cmd_prefix_; + /* Stores distance code in low 10 bits + and number of extra bits in high 6 bits. */ + uint16_t dist_prefix_; +} Command; + +/* distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1. */ +static BROTLI_INLINE void InitCommand(Command* self, + const BrotliDistanceParams* dist, size_t insertlen, + size_t copylen, int copylen_code_delta, size_t distance_code) { + /* Don't rely on signed int representation, use honest casts. */ + uint32_t delta = (uint8_t)((int8_t)copylen_code_delta); + self->insert_len_ = (uint32_t)insertlen; + self->copy_len_ = (uint32_t)(copylen | (delta << 25)); + /* The distance prefix and extra bits are stored in this Command as if + npostfix and ndirect were 0, they are only recomputed later after the + clustering if needed. */ + PrefixEncodeCopyDistance( + distance_code, dist->num_direct_distance_codes, + dist->distance_postfix_bits, &self->dist_prefix_, &self->dist_extra_); + GetLengthCode( + insertlen, (size_t)((int)copylen + copylen_code_delta), + TO_BROTLI_BOOL((self->dist_prefix_ & 0x3FF) == 0), &self->cmd_prefix_); +} + +static BROTLI_INLINE void InitInsertCommand(Command* self, size_t insertlen) { + self->insert_len_ = (uint32_t)insertlen; + self->copy_len_ = 4 << 25; + self->dist_extra_ = 0; + self->dist_prefix_ = BROTLI_NUM_DISTANCE_SHORT_CODES; + GetLengthCode(insertlen, 4, BROTLI_FALSE, &self->cmd_prefix_); +} + +static BROTLI_INLINE uint32_t CommandRestoreDistanceCode( + const Command* self, const BrotliDistanceParams* dist) { + if ((self->dist_prefix_ & 0x3FFu) < + BROTLI_NUM_DISTANCE_SHORT_CODES + dist->num_direct_distance_codes) { + return self->dist_prefix_ & 0x3FFu; + } else { + uint32_t dcode = self->dist_prefix_ & 0x3FFu; + uint32_t nbits = self->dist_prefix_ >> 10; + uint32_t extra = self->dist_extra_; + uint32_t postfix_mask = (1U << dist->distance_postfix_bits) - 1U; + uint32_t hcode = (dcode - dist->num_direct_distance_codes - + BROTLI_NUM_DISTANCE_SHORT_CODES) >> + dist->distance_postfix_bits; + uint32_t lcode = (dcode - dist->num_direct_distance_codes - + BROTLI_NUM_DISTANCE_SHORT_CODES) & postfix_mask; + uint32_t offset = ((2U + (hcode & 1U)) << nbits) - 4U; + return ((offset + extra) << dist->distance_postfix_bits) + lcode + + dist->num_direct_distance_codes + BROTLI_NUM_DISTANCE_SHORT_CODES; + } +} + +static BROTLI_INLINE uint32_t CommandDistanceContext(const Command* self) { + uint32_t r = self->cmd_prefix_ >> 6; + uint32_t c = self->cmd_prefix_ & 7; + if ((r == 0 || r == 2 || r == 4 || r == 7) && (c <= 2)) { + return c; + } + return 3; +} + +static BROTLI_INLINE uint32_t CommandCopyLen(const Command* self) { + return self->copy_len_ & 0x1FFFFFF; +} + +static BROTLI_INLINE uint32_t CommandCopyLenCode(const Command* self) { + uint32_t modifier = self->copy_len_ >> 25; + int32_t delta = (int8_t)((uint8_t)(modifier | ((modifier & 0x40) << 1))); + return (uint32_t)((int32_t)(self->copy_len_ & 0x1FFFFFF) + delta); +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_COMMAND_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/compound_dictionary.c b/packages/runtime/vendor/brotli/c/enc/compound_dictionary.c new file mode 100644 index 000000000..bf323a4b3 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/compound_dictionary.c @@ -0,0 +1,205 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "compound_dictionary.h" + +#include "../common/platform.h" +#include +#include "memory.h" + +static PreparedDictionary* CreatePreparedDictionaryWithParams(MemoryManager* m, + const uint8_t* source, size_t source_size, uint32_t bucket_bits, + uint32_t slot_bits, uint32_t hash_bits, uint16_t bucket_limit) { + /* Step 1: create "bloated" hasher. */ + uint32_t num_slots = 1u << slot_bits; + uint32_t num_buckets = 1u << bucket_bits; + uint32_t hash_shift = 64u - bucket_bits; + uint64_t hash_mask = (~((uint64_t)0U)) >> (64 - hash_bits); + uint32_t slot_mask = num_slots - 1; + size_t alloc_size = (sizeof(uint32_t) << slot_bits) + + (sizeof(uint32_t) << slot_bits) + + (sizeof(uint16_t) << bucket_bits) + + (sizeof(uint32_t) << bucket_bits) + + (sizeof(uint32_t) * source_size); + uint8_t* flat = NULL; + PreparedDictionary* result = NULL; + uint16_t* num = NULL; + uint32_t* bucket_heads = NULL; + uint32_t* next_bucket = NULL; + uint32_t* slot_offsets = NULL; + uint16_t* heads = NULL; + uint32_t* items = NULL; + uint8_t** source_ref = NULL; + uint32_t i; + uint32_t* slot_size = NULL; + uint32_t* slot_limit = NULL; + uint32_t total_items = 0; + if (slot_bits > 16) return NULL; + if (slot_bits > bucket_bits) return NULL; + if (bucket_bits - slot_bits >= 16) return NULL; + + flat = BROTLI_ALLOC(m, uint8_t, alloc_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(flat)) return NULL; + + slot_size = (uint32_t*)flat; + slot_limit = (uint32_t*)(&slot_size[num_slots]); + num = (uint16_t*)(&slot_limit[num_slots]); + bucket_heads = (uint32_t*)(&num[num_buckets]); + next_bucket = (uint32_t*)(&bucket_heads[num_buckets]); + memset(num, 0, num_buckets * sizeof(num[0])); + + /* TODO(eustas): apply custom "store" order. */ + for (i = 0; i + 7 < source_size; ++i) { + const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(&source[i]) & hash_mask) * + kPreparedDictionaryHashMul64Long; + const uint32_t key = (uint32_t)(h >> hash_shift); + uint16_t count = num[key]; + next_bucket[i] = (count == 0) ? ((uint32_t)(-1)) : bucket_heads[key]; + bucket_heads[key] = i; + count++; + if (count > bucket_limit) count = bucket_limit; + num[key] = count; + } + + /* Step 2: find slot limits. */ + for (i = 0; i < num_slots; ++i) { + BROTLI_BOOL overflow = BROTLI_FALSE; + slot_limit[i] = bucket_limit; + while (BROTLI_TRUE) { + uint32_t limit = slot_limit[i]; + size_t j; + uint32_t count = 0; + overflow = BROTLI_FALSE; + for (j = i; j < num_buckets; j += num_slots) { + uint32_t size = num[j]; + /* Last chain may span behind 64K limit; overflow happens only if + we are about to use 0xFFFF+ as item offset. */ + if (count >= 0xFFFF) { + overflow = BROTLI_TRUE; + break; + } + if (size > limit) size = limit; + count += size; + } + if (!overflow) { + slot_size[i] = count; + total_items += count; + break; + } + slot_limit[i]--; + } + } + + /* Step 3: transfer data to "slim" hasher. */ + alloc_size = sizeof(PreparedDictionary) + (sizeof(uint32_t) << slot_bits) + + (sizeof(uint16_t) << bucket_bits) + (sizeof(uint32_t) * total_items) + + sizeof(uint8_t*); + + result = (PreparedDictionary*)BROTLI_ALLOC(m, uint8_t, alloc_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(result)) { + BROTLI_FREE(m, flat); + return NULL; + } + slot_offsets = (uint32_t*)(&result[1]); + heads = (uint16_t*)(&slot_offsets[num_slots]); + items = (uint32_t*)(&heads[num_buckets]); + source_ref = (uint8_t**)(&items[total_items]); + + result->magic = kLeanPreparedDictionaryMagic; + result->num_items = total_items; + result->source_size = (uint32_t)source_size; + result->hash_bits = hash_bits; + result->bucket_bits = bucket_bits; + result->slot_bits = slot_bits; + BROTLI_UNALIGNED_STORE_PTR(source_ref, source); + + total_items = 0; + for (i = 0; i < num_slots; ++i) { + slot_offsets[i] = total_items; + total_items += slot_size[i]; + slot_size[i] = 0; + } + for (i = 0; i < num_buckets; ++i) { + uint32_t slot = i & slot_mask; + uint32_t count = num[i]; + uint32_t pos; + size_t j; + size_t cursor = slot_size[slot]; + if (count > slot_limit[slot]) count = slot_limit[slot]; + if (count == 0) { + heads[i] = 0xFFFF; + continue; + } + heads[i] = (uint16_t)cursor; + cursor += slot_offsets[slot]; + slot_size[slot] += count; + pos = bucket_heads[i]; + for (j = 0; j < count; j++) { + items[cursor++] = pos; + pos = next_bucket[pos]; + } + items[cursor - 1] |= 0x80000000; + } + + BROTLI_FREE(m, flat); + return result; +} + +PreparedDictionary* CreatePreparedDictionary(MemoryManager* m, + const uint8_t* source, size_t source_size) { + uint32_t bucket_bits = 17; + uint32_t slot_bits = 7; + uint32_t hash_bits = 40; + uint16_t bucket_limit = 32; + size_t volume = 16u << bucket_bits; + /* Tune parameters to fit dictionary size. */ + while (volume < source_size && bucket_bits < 22) { + bucket_bits++; + slot_bits++; + volume <<= 1; + } + return CreatePreparedDictionaryWithParams(m, + source, source_size, bucket_bits, slot_bits, hash_bits, bucket_limit); +} + +void DestroyPreparedDictionary(MemoryManager* m, + PreparedDictionary* dictionary) { + if (!dictionary) return; + BROTLI_FREE(m, dictionary); +} + +BROTLI_BOOL AttachPreparedDictionary( + CompoundDictionary* compound, const PreparedDictionary* dictionary) { + size_t length = 0; + size_t index = 0; + + if (compound->num_chunks == SHARED_BROTLI_MAX_COMPOUND_DICTS) { + return BROTLI_FALSE; + } + + if (!dictionary) return BROTLI_FALSE; + + length = dictionary->source_size; + index = compound->num_chunks; + compound->total_size += length; + compound->chunks[index] = dictionary; + compound->chunk_offsets[index + 1] = compound->total_size; + { + uint32_t* slot_offsets = (uint32_t*)(&dictionary[1]); + uint16_t* heads = (uint16_t*)(&slot_offsets[(size_t)1u << dictionary->slot_bits]); + uint32_t* items = (uint32_t*)(&heads[(size_t)1u << dictionary->bucket_bits]); + const void* tail = (void*)&items[dictionary->num_items]; + if (dictionary->magic == kPreparedDictionaryMagic) { + compound->chunk_source[index] = (const uint8_t*)tail; + } else { + /* dictionary->magic == kLeanPreparedDictionaryMagic */ + compound->chunk_source[index] = + (const uint8_t*)BROTLI_UNALIGNED_LOAD_PTR((const uint8_t**)tail); + } + } + compound->num_chunks++; + return BROTLI_TRUE; +} diff --git a/packages/runtime/vendor/brotli/c/enc/compound_dictionary.h b/packages/runtime/vendor/brotli/c/enc/compound_dictionary.h new file mode 100644 index 000000000..686f92fda --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/compound_dictionary.h @@ -0,0 +1,71 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#ifndef BROTLI_ENC_PREPARED_DICTIONARY_H_ +#define BROTLI_ENC_PREPARED_DICTIONARY_H_ + +#include "../common/platform.h" +#include +#include "memory.h" + +/* "Fat" prepared dictionary, could be cooked outside of C implementation, + * e.g. on Java side. LZ77 data is copied inside PreparedDictionary struct. */ +static const uint32_t kPreparedDictionaryMagic = 0xDEBCEDE0; + +static const uint32_t kSharedDictionaryMagic = 0xDEBCEDE1; + +static const uint32_t kManagedDictionaryMagic = 0xDEBCEDE2; + +/* "Lean" prepared dictionary. LZ77 data is referenced. It is the responsibility + * of caller of "prepare dictionary" to keep the LZ77 data while prepared + * dictionary is in use. */ +static const uint32_t kLeanPreparedDictionaryMagic = 0xDEBCEDE3; + +static const uint64_t kPreparedDictionaryHashMul64Long = + BROTLI_MAKE_UINT64_T(0x1FE35A7Bu, 0xD3579BD3u); + +typedef struct PreparedDictionary { + uint32_t magic; + uint32_t num_items; + uint32_t source_size; + uint32_t hash_bits; + uint32_t bucket_bits; + uint32_t slot_bits; + + /* --- Dynamic size members --- */ + + /* uint32_t slot_offsets[1 << slot_bits]; */ + /* uint16_t heads[1 << bucket_bits]; */ + /* uint32_t items[variable]; */ + + /* [maybe] uint8_t* source_ref, depending on magic. */ + /* [maybe] uint8_t source[source_size], depending on magic. */ +} PreparedDictionary; + +BROTLI_INTERNAL PreparedDictionary* CreatePreparedDictionary(MemoryManager* m, + const uint8_t* source, size_t source_size); + +BROTLI_INTERNAL void DestroyPreparedDictionary(MemoryManager* m, + PreparedDictionary* dictionary); + +typedef struct CompoundDictionary { + /* LZ77 prefix, compound dictionary */ + size_t num_chunks; + size_t total_size; + /* Client instances. */ + const PreparedDictionary* chunks[SHARED_BROTLI_MAX_COMPOUND_DICTS + 1]; + const uint8_t* chunk_source[SHARED_BROTLI_MAX_COMPOUND_DICTS + 1]; + size_t chunk_offsets[SHARED_BROTLI_MAX_COMPOUND_DICTS + 1]; + + size_t num_prepared_instances_; + /* Owned instances. */ + PreparedDictionary* prepared_instances_[SHARED_BROTLI_MAX_COMPOUND_DICTS + 1]; +} CompoundDictionary; + +BROTLI_INTERNAL BROTLI_BOOL AttachPreparedDictionary( + CompoundDictionary* compound, const PreparedDictionary* dictionary); + +#endif /* BROTLI_ENC_PREPARED_DICTIONARY */ diff --git a/packages/runtime/vendor/brotli/c/enc/compress_fragment.c b/packages/runtime/vendor/brotli/c/enc/compress_fragment.c new file mode 100644 index 000000000..14fec4fbf --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/compress_fragment.c @@ -0,0 +1,790 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function for fast encoding of an input fragment, independently from the input + history. This function uses one-pass processing: when we find a backward + match, we immediately emit the corresponding command and literal codes to + the bit stream. + + Adapted from the CompressFragment() function in + https://github.com/google/snappy/blob/master/snappy.cc */ + +#include "compress_fragment.h" + +#include "../common/constants.h" +#include "../common/platform.h" +#include "brotli_bit_stream.h" +#include "entropy_encode.h" +#include "fast_log.h" +#include "find_match_length.h" +#include "hash_base.h" +#include "write_bits.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define MAX_DISTANCE (long)BROTLI_MAX_BACKWARD_LIMIT(18) + +static BROTLI_INLINE uint32_t Hash(const uint8_t* p, size_t shift) { + const uint64_t h = (BROTLI_UNALIGNED_LOAD64LE(p) << 24) * kHashMul32; + return (uint32_t)(h >> shift); +} + +static BROTLI_INLINE uint32_t HashBytesAtOffset( + uint64_t v, int offset, size_t shift) { + BROTLI_DCHECK(offset >= 0); + BROTLI_DCHECK(offset <= 3); + { + const uint64_t h = ((v >> (8 * offset)) << 24) * kHashMul32; + return (uint32_t)(h >> shift); + } +} + +static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2) { + return TO_BROTLI_BOOL( + BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2) && + p1[4] == p2[4]); +} + +/* Builds a literal prefix code into "depths" and "bits" based on the statistics + of the "input" string and stores it into the bit stream. + Note that the prefix code here is built from the pre-LZ77 input, therefore + we can only approximate the statistics of the actual literal stream. + Moreover, for long inputs we build a histogram from a sample of the input + and thus have to assign a non-zero depth for each literal. + Returns estimated compression ratio millibytes/char for encoding given input + with generated code. */ +static size_t BuildAndStoreLiteralPrefixCode(BrotliOnePassArena* s, + const uint8_t* input, + const size_t input_size, + uint8_t depths[256], + uint16_t bits[256], + size_t* storage_ix, + uint8_t* storage) { + uint32_t* BROTLI_RESTRICT const histogram = s->histogram; + size_t histogram_total; + size_t i; + memset(histogram, 0, sizeof(s->histogram)); + + if (input_size < (1 << 15)) { + for (i = 0; i < input_size; ++i) { + ++histogram[input[i]]; + } + histogram_total = input_size; + for (i = 0; i < 256; ++i) { + /* We weigh the first 11 samples with weight 3 to account for the + balancing effect of the LZ77 phase on the histogram. */ + const uint32_t adjust = 2 * BROTLI_MIN(uint32_t, histogram[i], 11u); + histogram[i] += adjust; + histogram_total += adjust; + } + } else { + static const size_t kSampleRate = 29; + for (i = 0; i < input_size; i += kSampleRate) { + ++histogram[input[i]]; + } + histogram_total = (input_size + kSampleRate - 1) / kSampleRate; + for (i = 0; i < 256; ++i) { + /* We add 1 to each population count to avoid 0 bit depths (since this is + only a sample and we don't know if the symbol appears or not), and we + weigh the first 11 samples with weight 3 to account for the balancing + effect of the LZ77 phase on the histogram (more frequent symbols are + more likely to be in backward references instead as literals). */ + const uint32_t adjust = 1 + 2 * BROTLI_MIN(uint32_t, histogram[i], 11u); + histogram[i] += adjust; + histogram_total += adjust; + } + } + BrotliBuildAndStoreHuffmanTreeFast(s->tree, histogram, histogram_total, + /* max_bits = */ 8, + depths, bits, storage_ix, storage); + { + size_t literal_ratio = 0; + for (i = 0; i < 256; ++i) { + if (histogram[i]) literal_ratio += histogram[i] * depths[i]; + } + /* Estimated encoding ratio, millibytes per symbol. */ + return (literal_ratio * 125) / histogram_total; + } +} + +/* Builds a command and distance prefix code (each 64 symbols) into "depth" and + "bits" based on "histogram" and stores it into the bit stream. */ +static void BuildAndStoreCommandPrefixCode(BrotliOnePassArena* s, + size_t* storage_ix, uint8_t* storage) { + const uint32_t* const histogram = s->cmd_histo; + uint8_t* const depth = s->cmd_depth; + uint16_t* const bits = s->cmd_bits; + uint8_t* BROTLI_RESTRICT const tmp_depth = s->tmp_depth; + uint16_t* BROTLI_RESTRICT const tmp_bits = s->tmp_bits; + /* TODO(eustas): do only once on initialization. */ + memset(tmp_depth, 0, BROTLI_NUM_COMMAND_SYMBOLS); + + BrotliCreateHuffmanTree(histogram, 64, 15, s->tree, depth); + BrotliCreateHuffmanTree(&histogram[64], 64, 14, s->tree, &depth[64]); + /* We have to jump through a few hoops here in order to compute + the command bits because the symbols are in a different order than in + the full alphabet. This looks complicated, but having the symbols + in this order in the command bits saves a few branches in the Emit* + functions. */ + memcpy(tmp_depth, depth, 24); + memcpy(tmp_depth + 24, depth + 40, 8); + memcpy(tmp_depth + 32, depth + 24, 8); + memcpy(tmp_depth + 40, depth + 48, 8); + memcpy(tmp_depth + 48, depth + 32, 8); + memcpy(tmp_depth + 56, depth + 56, 8); + BrotliConvertBitDepthsToSymbols(tmp_depth, 64, tmp_bits); + memcpy(bits, tmp_bits, 48); + memcpy(bits + 24, tmp_bits + 32, 16); + memcpy(bits + 32, tmp_bits + 48, 16); + memcpy(bits + 40, tmp_bits + 24, 16); + memcpy(bits + 48, tmp_bits + 40, 16); + memcpy(bits + 56, tmp_bits + 56, 16); + BrotliConvertBitDepthsToSymbols(&depth[64], 64, &bits[64]); + { + /* Create the bit length array for the full command alphabet. */ + size_t i; + memset(tmp_depth, 0, 64); /* only 64 first values were used */ + memcpy(tmp_depth, depth, 8); + memcpy(tmp_depth + 64, depth + 8, 8); + memcpy(tmp_depth + 128, depth + 16, 8); + memcpy(tmp_depth + 192, depth + 24, 8); + memcpy(tmp_depth + 384, depth + 32, 8); + for (i = 0; i < 8; ++i) { + tmp_depth[128 + 8 * i] = depth[40 + i]; + tmp_depth[256 + 8 * i] = depth[48 + i]; + tmp_depth[448 + 8 * i] = depth[56 + i]; + } + /* TODO(eustas): could/should full-length machinery be avoided? */ + BrotliStoreHuffmanTree( + tmp_depth, BROTLI_NUM_COMMAND_SYMBOLS, s->tree, storage_ix, storage); + } + BrotliStoreHuffmanTree(&depth[64], 64, s->tree, storage_ix, storage); +} + +/* REQUIRES: insertlen < 6210 */ +static BROTLI_INLINE void EmitInsertLen(size_t insertlen, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, + uint8_t* storage) { + if (insertlen < 6) { + const size_t code = insertlen + 40; + BrotliWriteBits(depth[code], bits[code], storage_ix, storage); + ++histo[code]; + } else if (insertlen < 130) { + const size_t tail = insertlen - 2; + const uint32_t nbits = Log2FloorNonZero(tail) - 1u; + const size_t prefix = tail >> nbits; + const size_t inscode = (nbits << 1) + prefix + 42; + BrotliWriteBits(depth[inscode], bits[inscode], storage_ix, storage); + BrotliWriteBits(nbits, tail - (prefix << nbits), storage_ix, storage); + ++histo[inscode]; + } else if (insertlen < 2114) { + const size_t tail = insertlen - 66; + const uint32_t nbits = Log2FloorNonZero(tail); + const size_t code = nbits + 50; + BrotliWriteBits(depth[code], bits[code], storage_ix, storage); + BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage); + ++histo[code]; + } else { + BrotliWriteBits(depth[61], bits[61], storage_ix, storage); + BrotliWriteBits(12, insertlen - 2114, storage_ix, storage); + ++histo[61]; + } +} + +static BROTLI_INLINE void EmitLongInsertLen(size_t insertlen, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, + uint8_t* storage) { + if (insertlen < 22594) { + BrotliWriteBits(depth[62], bits[62], storage_ix, storage); + BrotliWriteBits(14, insertlen - 6210, storage_ix, storage); + ++histo[62]; + } else { + BrotliWriteBits(depth[63], bits[63], storage_ix, storage); + BrotliWriteBits(24, insertlen - 22594, storage_ix, storage); + ++histo[63]; + } +} + +static BROTLI_INLINE void EmitCopyLen(size_t copylen, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, + uint8_t* storage) { + if (copylen < 10) { + BrotliWriteBits( + depth[copylen + 14], bits[copylen + 14], storage_ix, storage); + ++histo[copylen + 14]; + } else if (copylen < 134) { + const size_t tail = copylen - 6; + const uint32_t nbits = Log2FloorNonZero(tail) - 1u; + const size_t prefix = tail >> nbits; + const size_t code = (nbits << 1) + prefix + 20; + BrotliWriteBits(depth[code], bits[code], storage_ix, storage); + BrotliWriteBits(nbits, tail - (prefix << nbits), storage_ix, storage); + ++histo[code]; + } else if (copylen < 2118) { + const size_t tail = copylen - 70; + const uint32_t nbits = Log2FloorNonZero(tail); + const size_t code = nbits + 28; + BrotliWriteBits(depth[code], bits[code], storage_ix, storage); + BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage); + ++histo[code]; + } else { + BrotliWriteBits(depth[39], bits[39], storage_ix, storage); + BrotliWriteBits(24, copylen - 2118, storage_ix, storage); + ++histo[39]; + } +} + +static BROTLI_INLINE void EmitCopyLenLastDistance(size_t copylen, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, + uint8_t* storage) { + if (copylen < 12) { + BrotliWriteBits(depth[copylen - 4], bits[copylen - 4], storage_ix, storage); + ++histo[copylen - 4]; + } else if (copylen < 72) { + const size_t tail = copylen - 8; + const uint32_t nbits = Log2FloorNonZero(tail) - 1; + const size_t prefix = tail >> nbits; + const size_t code = (nbits << 1) + prefix + 4; + BrotliWriteBits(depth[code], bits[code], storage_ix, storage); + BrotliWriteBits(nbits, tail - (prefix << nbits), storage_ix, storage); + ++histo[code]; + } else if (copylen < 136) { + const size_t tail = copylen - 8; + const size_t code = (tail >> 5) + 30; + BrotliWriteBits(depth[code], bits[code], storage_ix, storage); + BrotliWriteBits(5, tail & 31, storage_ix, storage); + BrotliWriteBits(depth[64], bits[64], storage_ix, storage); + ++histo[code]; + ++histo[64]; + } else if (copylen < 2120) { + const size_t tail = copylen - 72; + const uint32_t nbits = Log2FloorNonZero(tail); + const size_t code = nbits + 28; + BrotliWriteBits(depth[code], bits[code], storage_ix, storage); + BrotliWriteBits(nbits, tail - ((size_t)1 << nbits), storage_ix, storage); + BrotliWriteBits(depth[64], bits[64], storage_ix, storage); + ++histo[code]; + ++histo[64]; + } else { + BrotliWriteBits(depth[39], bits[39], storage_ix, storage); + BrotliWriteBits(24, copylen - 2120, storage_ix, storage); + BrotliWriteBits(depth[64], bits[64], storage_ix, storage); + ++histo[39]; + ++histo[64]; + } +} + +static BROTLI_INLINE void EmitDistance(size_t distance, + const uint8_t depth[128], + const uint16_t bits[128], + uint32_t histo[128], + size_t* storage_ix, uint8_t* storage) { + const size_t d = distance + 3; + const uint32_t nbits = Log2FloorNonZero(d) - 1u; + const size_t prefix = (d >> nbits) & 1; + const size_t offset = (2 + prefix) << nbits; + const size_t distcode = 2 * (nbits - 1) + prefix + 80; + BrotliWriteBits(depth[distcode], bits[distcode], storage_ix, storage); + BrotliWriteBits(nbits, d - offset, storage_ix, storage); + ++histo[distcode]; +} + +static BROTLI_INLINE void EmitLiterals(const uint8_t* input, const size_t len, + const uint8_t depth[256], + const uint16_t bits[256], + size_t* storage_ix, uint8_t* storage) { + size_t j; + for (j = 0; j < len; j++) { + const uint8_t lit = input[j]; + BrotliWriteBits(depth[lit], bits[lit], storage_ix, storage); + } +} + +/* REQUIRES: len <= 1 << 24. */ +static void BrotliStoreMetaBlockHeader( + size_t len, BROTLI_BOOL is_uncompressed, size_t* storage_ix, + uint8_t* storage) { + size_t nibbles = 6; + /* ISLAST */ + BrotliWriteBits(1, 0, storage_ix, storage); + if (len <= (1U << 16)) { + nibbles = 4; + } else if (len <= (1U << 20)) { + nibbles = 5; + } + BrotliWriteBits(2, nibbles - 4, storage_ix, storage); + BrotliWriteBits(nibbles * 4, len - 1, storage_ix, storage); + /* ISUNCOMPRESSED */ + BrotliWriteBits(1, (uint64_t)is_uncompressed, storage_ix, storage); +} + +static void UpdateBits(size_t n_bits, uint32_t bits, size_t pos, + uint8_t* array) { + while (n_bits > 0) { + size_t byte_pos = pos >> 3; + size_t n_unchanged_bits = pos & 7; + size_t n_changed_bits = BROTLI_MIN(size_t, n_bits, 8 - n_unchanged_bits); + size_t total_bits = n_unchanged_bits + n_changed_bits; + uint32_t mask = + (~((1u << total_bits) - 1u)) | ((1u << n_unchanged_bits) - 1u); + uint32_t unchanged_bits = array[byte_pos] & mask; + uint32_t changed_bits = bits & ((1u << n_changed_bits) - 1u); + array[byte_pos] = + (uint8_t)((changed_bits << n_unchanged_bits) | unchanged_bits); + n_bits -= n_changed_bits; + bits >>= n_changed_bits; + pos += n_changed_bits; + } +} + +static void RewindBitPosition(const size_t new_storage_ix, + size_t* storage_ix, uint8_t* storage) { + const size_t bitpos = new_storage_ix & 7; + const size_t mask = (1u << bitpos) - 1; + storage[new_storage_ix >> 3] &= (uint8_t)mask; + *storage_ix = new_storage_ix; +} + +static BROTLI_BOOL ShouldMergeBlock(BrotliOnePassArena* s, + const uint8_t* data, size_t len, const uint8_t* depths) { + uint32_t* BROTLI_RESTRICT const histo = s->histogram; + static const size_t kSampleRate = 43; + size_t i; + memset(histo, 0, sizeof(s->histogram)); + for (i = 0; i < len; i += kSampleRate) { + ++histo[data[i]]; + } + { + const size_t total = (len + kSampleRate - 1) / kSampleRate; + double r = (FastLog2(total) + 0.5) * (double)total + 200; + for (i = 0; i < 256; ++i) { + r -= (double)histo[i] * (depths[i] + FastLog2(histo[i])); + } + return TO_BROTLI_BOOL(r >= 0.0); + } +} + +/* Acceptable loss for uncompressible speedup is 2% */ +#define MIN_RATIO 980 + +static BROTLI_INLINE BROTLI_BOOL ShouldUseUncompressedMode( + const uint8_t* metablock_start, const uint8_t* next_emit, + const size_t insertlen, const size_t literal_ratio) { + const size_t compressed = (size_t)(next_emit - metablock_start); + if (compressed * 50 > insertlen) { + return BROTLI_FALSE; + } else { + return TO_BROTLI_BOOL(literal_ratio > MIN_RATIO); + } +} + +static void EmitUncompressedMetaBlock(const uint8_t* begin, const uint8_t* end, + const size_t storage_ix_start, + size_t* storage_ix, uint8_t* storage) { + const size_t len = (size_t)(end - begin); + RewindBitPosition(storage_ix_start, storage_ix, storage); + BrotliStoreMetaBlockHeader(len, 1, storage_ix, storage); + *storage_ix = (*storage_ix + 7u) & ~7u; + memcpy(&storage[*storage_ix >> 3], begin, len); + *storage_ix += len << 3; + storage[*storage_ix >> 3] = 0; +} + +static BROTLI_MODEL("small") uint32_t kCmdHistoSeed[128] = { + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 0, 0, 0, 0, +}; + +static BROTLI_INLINE void BrotliCompressFragmentFastImpl( + BrotliOnePassArena* s, const uint8_t* input, size_t input_size, + BROTLI_BOOL is_last, int* table, size_t table_bits, + size_t* storage_ix, uint8_t* storage) { + uint8_t* BROTLI_RESTRICT const cmd_depth = s->cmd_depth; + uint16_t* BROTLI_RESTRICT const cmd_bits = s->cmd_bits; + uint32_t* BROTLI_RESTRICT const cmd_histo = s->cmd_histo; + uint8_t* BROTLI_RESTRICT const lit_depth = s->lit_depth; + uint16_t* BROTLI_RESTRICT const lit_bits = s->lit_bits; + const uint8_t* ip_end; + + /* "next_emit" is a pointer to the first byte that is not covered by a + previous copy. Bytes between "next_emit" and the start of the next copy or + the end of the input will be emitted as literal bytes. */ + const uint8_t* next_emit = input; + /* Save the start of the first block for position and distance computations. + */ + const uint8_t* base_ip = input; + + static const size_t kFirstBlockSize = 3 << 15; + static const size_t kMergeBlockSize = 1 << 16; + + const size_t kInputMarginBytes = BROTLI_WINDOW_GAP; + const size_t kMinMatchLen = 5; + + const uint8_t* metablock_start = input; + size_t block_size = BROTLI_MIN(size_t, input_size, kFirstBlockSize); + size_t total_block_size = block_size; + /* Save the bit position of the MLEN field of the meta-block header, so that + we can update it later if we decide to extend this meta-block. */ + size_t mlen_storage_ix = *storage_ix + 3; + + size_t literal_ratio; + + const uint8_t* ip; + int last_distance; + + const size_t shift = 64u - table_bits; + + BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage); + /* No block splits, no contexts. */ + BrotliWriteBits(13, 0, storage_ix, storage); + + literal_ratio = BuildAndStoreLiteralPrefixCode( + s, input, block_size, s->lit_depth, s->lit_bits, storage_ix, storage); + + { + /* Store the pre-compressed command and distance prefix codes. */ + size_t i; + for (i = 0; i + 7 < s->cmd_code_numbits; i += 8) { + BrotliWriteBits(8, s->cmd_code[i >> 3], storage_ix, storage); + } + } + BrotliWriteBits(s->cmd_code_numbits & 7, + s->cmd_code[s->cmd_code_numbits >> 3], storage_ix, storage); + + emit_commands: + /* Initialize the command and distance histograms. We will gather + statistics of command and distance codes during the processing + of this block and use it to update the command and distance + prefix codes for the next block. */ + memcpy(s->cmd_histo, kCmdHistoSeed, sizeof(kCmdHistoSeed)); + + /* "ip" is the input pointer. */ + ip = input; + last_distance = -1; + ip_end = input + block_size; + + if (BROTLI_PREDICT_TRUE(block_size >= kInputMarginBytes)) { + /* For the last block, we need to keep a 16 bytes margin so that we can be + sure that all distances are at most window size - 16. + For all other blocks, we only need to keep a margin of 5 bytes so that + we don't go over the block size with a copy. */ + const size_t len_limit = BROTLI_MIN(size_t, block_size - kMinMatchLen, + input_size - kInputMarginBytes); + const uint8_t* ip_limit = input + len_limit; + + uint32_t next_hash; + for (next_hash = Hash(++ip, shift); ; ) { + /* Step 1: Scan forward in the input looking for a 5-byte-long match. + If we get close to exhausting the input then goto emit_remainder. + + Heuristic match skipping: If 32 bytes are scanned with no matches + found, start looking only at every other byte. If 32 more bytes are + scanned, look at every third byte, etc.. When a match is found, + immediately go back to looking at every byte. This is a small loss + (~5% performance, ~0.1% density) for compressible data due to more + bookkeeping, but for non-compressible data (such as JPEG) it's a huge + win since the compressor quickly "realizes" the data is incompressible + and doesn't bother looking for matches everywhere. + + The "skip" variable keeps track of how many bytes there are since the + last match; dividing it by 32 (i.e. right-shifting by five) gives the + number of bytes to move ahead for each iteration. */ + uint32_t skip = 32; + + const uint8_t* next_ip = ip; + const uint8_t* candidate; + BROTLI_DCHECK(next_emit < ip); +trawl: + do { + uint32_t hash = next_hash; + uint32_t bytes_between_hash_lookups = skip++ >> 5; + BROTLI_DCHECK(hash == Hash(next_ip, shift)); + ip = next_ip; + next_ip = ip + bytes_between_hash_lookups; + if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) { + goto emit_remainder; + } + next_hash = Hash(next_ip, shift); + candidate = ip - last_distance; + if (IsMatch(ip, candidate)) { + if (BROTLI_PREDICT_TRUE(candidate < ip)) { + table[hash] = (int)(ip - base_ip); + break; + } + } + candidate = base_ip + table[hash]; + BROTLI_DCHECK(candidate >= base_ip); + BROTLI_DCHECK(candidate < ip); + + table[hash] = (int)(ip - base_ip); + } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate))); + + /* Check copy distance. If candidate is not feasible, continue search. + Checking is done outside of hot loop to reduce overhead. */ + if (ip - candidate > MAX_DISTANCE) goto trawl; + + /* Step 2: Emit the found match together with the literal bytes from + "next_emit" to the bit stream, and then see if we can find a next match + immediately afterwards. Repeat until we find no match for the input + without emitting some literal bytes. */ + + { + /* We have a 5-byte match at ip, and we need to emit bytes in + [next_emit, ip). */ + const uint8_t* base = ip; + size_t matched = 5 + FindMatchLengthWithLimit( + candidate + 5, ip + 5, (size_t)(ip_end - ip) - 5); + int distance = (int)(base - candidate); /* > 0 */ + size_t insert = (size_t)(base - next_emit); + ip += matched; + BROTLI_LOG(("[CompressFragment] pos = %d insert = %lu copy = %d\n", + (int)(next_emit - base_ip), (unsigned long)insert, 2)); + BROTLI_DCHECK(0 == memcmp(base, candidate, matched)); + if (BROTLI_PREDICT_TRUE(insert < 6210)) { + EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert, + literal_ratio)) { + EmitUncompressedMetaBlock(metablock_start, base, mlen_storage_ix - 3, + storage_ix, storage); + input_size -= (size_t)(base - input); + input = base; + next_emit = input; + goto next_block; + } else { + EmitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + } + EmitLiterals(next_emit, insert, lit_depth, lit_bits, + storage_ix, storage); + if (distance == last_distance) { + BrotliWriteBits(cmd_depth[64], cmd_bits[64], storage_ix, storage); + ++cmd_histo[64]; + } else { + EmitDistance((size_t)distance, cmd_depth, cmd_bits, + cmd_histo, storage_ix, storage); + last_distance = distance; + } + EmitCopyLenLastDistance(matched, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + BROTLI_LOG(("[CompressFragment] pos = %d distance = %d\n" + "[CompressFragment] pos = %d insert = %d copy = %d\n" + "[CompressFragment] pos = %d distance = %d\n", + (int)(base - base_ip), (int)distance, + (int)(base - base_ip) + 2, 0, (int)matched - 2, + (int)(base - base_ip) + 2, (int)distance)); + + next_emit = ip; + if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) { + goto emit_remainder; + } + /* We could immediately start working at ip now, but to improve + compression we first update "table" with the hashes of some positions + within the last copy. */ + { + uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3); + uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift); + uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift); + table[prev_hash] = (int)(ip - base_ip - 3); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift); + table[prev_hash] = (int)(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift); + table[prev_hash] = (int)(ip - base_ip - 1); + + candidate = base_ip + table[cur_hash]; + table[cur_hash] = (int)(ip - base_ip); + } + } + + while (IsMatch(ip, candidate)) { + /* We have a 5-byte match at ip, and no need to emit any literal bytes + prior to ip. */ + const uint8_t* base = ip; + size_t matched = 5 + FindMatchLengthWithLimit( + candidate + 5, ip + 5, (size_t)(ip_end - ip) - 5); + if (ip - candidate > MAX_DISTANCE) break; + ip += matched; + last_distance = (int)(base - candidate); /* > 0 */ + BROTLI_DCHECK(0 == memcmp(base, candidate, matched)); + EmitCopyLen(matched, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + EmitDistance((size_t)last_distance, cmd_depth, cmd_bits, + cmd_histo, storage_ix, storage); + BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n" + "[CompressFragment] pos = %d distance = %d\n", + (int)(base - base_ip), 0, (int)matched, + (int)(base - base_ip), (int)last_distance)); + + next_emit = ip; + if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) { + goto emit_remainder; + } + /* We could immediately start working at ip now, but to improve + compression we first update "table" with the hashes of some positions + within the last copy. */ + { + uint64_t input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3); + uint32_t prev_hash = HashBytesAtOffset(input_bytes, 0, shift); + uint32_t cur_hash = HashBytesAtOffset(input_bytes, 3, shift); + table[prev_hash] = (int)(ip - base_ip - 3); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift); + table[prev_hash] = (int)(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift); + table[prev_hash] = (int)(ip - base_ip - 1); + + candidate = base_ip + table[cur_hash]; + table[cur_hash] = (int)(ip - base_ip); + } + } + + next_hash = Hash(++ip, shift); + } + } + + emit_remainder: + BROTLI_DCHECK(next_emit <= ip_end); + input += block_size; + input_size -= block_size; + block_size = BROTLI_MIN(size_t, input_size, kMergeBlockSize); + + /* Decide if we want to continue this meta-block instead of emitting the + last insert-only command. */ + if (input_size > 0 && + total_block_size + block_size <= (1 << 20) && + ShouldMergeBlock(s, input, block_size, lit_depth)) { + BROTLI_DCHECK(total_block_size > (1 << 16)); + /* Update the size of the current meta-block and continue emitting commands. + We can do this because the current size and the new size both have 5 + nibbles. */ + total_block_size += block_size; + UpdateBits(20, (uint32_t)(total_block_size - 1), mlen_storage_ix, storage); + goto emit_commands; + } + + /* Emit the remaining bytes as literals. */ + if (next_emit < ip_end) { + const size_t insert = (size_t)(ip_end - next_emit); + BROTLI_LOG(("[CompressFragment] pos = %d insert = %lu copy = %d\n", + (int)(next_emit - base_ip), (unsigned long)insert, 2)); + if (BROTLI_PREDICT_TRUE(insert < 6210)) { + EmitInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + EmitLiterals(next_emit, insert, lit_depth, lit_bits, storage_ix, storage); + } else if (ShouldUseUncompressedMode(metablock_start, next_emit, insert, + literal_ratio)) { + EmitUncompressedMetaBlock(metablock_start, ip_end, mlen_storage_ix - 3, + storage_ix, storage); + } else { + EmitLongInsertLen(insert, cmd_depth, cmd_bits, cmd_histo, + storage_ix, storage); + EmitLiterals(next_emit, insert, lit_depth, lit_bits, + storage_ix, storage); + } + } + next_emit = ip_end; + +next_block: + /* If we have more data, write a new meta-block header and prefix codes and + then continue emitting commands. */ + if (input_size > 0) { + metablock_start = input; + block_size = BROTLI_MIN(size_t, input_size, kFirstBlockSize); + total_block_size = block_size; + /* Save the bit position of the MLEN field of the meta-block header, so that + we can update it later if we decide to extend this meta-block. */ + mlen_storage_ix = *storage_ix + 3; + BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage); + /* No block splits, no contexts. */ + BrotliWriteBits(13, 0, storage_ix, storage); + literal_ratio = BuildAndStoreLiteralPrefixCode( + s, input, block_size, lit_depth, lit_bits, storage_ix, storage); + BuildAndStoreCommandPrefixCode(s, storage_ix, storage); + goto emit_commands; + } + + if (!is_last) { + /* If this is not the last block, update the command and distance prefix + codes for the next block and store the compressed forms. */ + s->cmd_code[0] = 0; + s->cmd_code_numbits = 0; + BuildAndStoreCommandPrefixCode(s, &s->cmd_code_numbits, s->cmd_code); + } +} + +#define FOR_TABLE_BITS_(X) X(9) X(11) X(13) X(15) + +#define BAKE_METHOD_PARAM_(B) \ +static BROTLI_NOINLINE void BrotliCompressFragmentFastImpl ## B( \ + BrotliOnePassArena* s, const uint8_t* input, size_t input_size, \ + BROTLI_BOOL is_last, int* table, size_t* storage_ix, uint8_t* storage) { \ + BrotliCompressFragmentFastImpl(s, input, input_size, is_last, table, B, \ + storage_ix, storage); \ +} +FOR_TABLE_BITS_(BAKE_METHOD_PARAM_) +#undef BAKE_METHOD_PARAM_ + +void BrotliCompressFragmentFast( + BrotliOnePassArena* s, const uint8_t* input, size_t input_size, + BROTLI_BOOL is_last, int* table, size_t table_size, + size_t* storage_ix, uint8_t* storage) { + const size_t initial_storage_ix = *storage_ix; + const size_t table_bits = Log2FloorNonZero(table_size); + + if (input_size == 0) { + BROTLI_DCHECK(is_last); + BrotliWriteBits(1, 1, storage_ix, storage); /* islast */ + BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */ + *storage_ix = (*storage_ix + 7u) & ~7u; + return; + } + + switch (table_bits) { +#define CASE_(B) \ + case B: \ + BrotliCompressFragmentFastImpl ## B( \ + s, input, input_size, is_last, table, storage_ix, storage);\ + break; + FOR_TABLE_BITS_(CASE_) +#undef CASE_ + default: BROTLI_DCHECK(0); break; + } + + /* If output is larger than single uncompressed block, rewrite it. */ + if (*storage_ix - initial_storage_ix > 31 + (input_size << 3)) { + EmitUncompressedMetaBlock(input, input + input_size, initial_storage_ix, + storage_ix, storage); + } + + if (is_last) { + BrotliWriteBits(1, 1, storage_ix, storage); /* islast */ + BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */ + *storage_ix = (*storage_ix + 7u) & ~7u; + } +} + +#undef FOR_TABLE_BITS_ + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/compress_fragment.h b/packages/runtime/vendor/brotli/c/enc/compress_fragment.h new file mode 100644 index 000000000..462f366b3 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/compress_fragment.h @@ -0,0 +1,84 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function for fast encoding of an input fragment, independently from the input + history. This function uses one-pass processing: when we find a backward + match, we immediately emit the corresponding command and literal codes to + the bit stream. */ + +#ifndef BROTLI_ENC_COMPRESS_FRAGMENT_H_ +#define BROTLI_ENC_COMPRESS_FRAGMENT_H_ + +#include "../common/constants.h" +#include "../common/platform.h" +#include "entropy_encode.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct BrotliOnePassArena { + uint8_t lit_depth[256]; + uint16_t lit_bits[256]; + + /* Command and distance prefix codes (each 64 symbols, stored back-to-back) + used for the next block. The command prefix code is over a smaller alphabet + with the following 64 symbols: + 0 - 15: insert length code 0, copy length code 0 - 15, same distance + 16 - 39: insert length code 0, copy length code 0 - 23 + 40 - 63: insert length code 0 - 23, copy length code 0 + Note that symbols 16 and 40 represent the same code in the full alphabet, + but we do not use either of them. */ + uint8_t cmd_depth[128]; + uint16_t cmd_bits[128]; + uint32_t cmd_histo[128]; + + /* The compressed form of the command and distance prefix codes for the next + block. */ + uint8_t cmd_code[512]; + size_t cmd_code_numbits; + + HuffmanTree tree[2 * BROTLI_NUM_LITERAL_SYMBOLS + 1]; + uint32_t histogram[256]; + uint8_t tmp_depth[BROTLI_NUM_COMMAND_SYMBOLS]; + uint16_t tmp_bits[64]; +} BrotliOnePassArena; + +/* Compresses "input" string to the "*storage" buffer as one or more complete + meta-blocks, and updates the "*storage_ix" bit position. + + If "is_last" is 1, emits an additional empty last meta-block. + + "cmd_depth" and "cmd_bits" contain the command and distance prefix codes + (see comment in encode.h) used for the encoding of this input fragment. + If "is_last" is 0, they are updated to reflect the statistics + of this input fragment, to be used for the encoding of the next fragment. + + "*cmd_code_numbits" is the number of bits of the compressed representation + of the command and distance prefix codes, and "cmd_code" is an array of + at least "(*cmd_code_numbits + 7) >> 3" size that contains the compressed + command and distance prefix codes. If "is_last" is 0, these are also + updated to represent the updated "cmd_depth" and "cmd_bits". + + REQUIRES: "input_size" is greater than zero, or "is_last" is 1. + REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24). + REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. + REQUIRES: "table_size" is an odd (9, 11, 13, 15) power of two + OUTPUT: maximal copy distance <= |input_size| + OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ +BROTLI_INTERNAL void BrotliCompressFragmentFast(BrotliOnePassArena* s, + const uint8_t* input, + size_t input_size, + BROTLI_BOOL is_last, + int* table, size_t table_size, + size_t* storage_ix, + uint8_t* storage); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_COMPRESS_FRAGMENT_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/compress_fragment_two_pass.c b/packages/runtime/vendor/brotli/c/enc/compress_fragment_two_pass.c new file mode 100644 index 000000000..01e4794d8 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/compress_fragment_two_pass.c @@ -0,0 +1,647 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function for fast encoding of an input fragment, independently from the input + history. This function uses two-pass processing: in the first pass we save + the found backward matches and literal bytes into a buffer, and in the + second pass we emit them into the bit stream using prefix codes built based + on the actual command and literal byte histograms. */ + +#include "compress_fragment_two_pass.h" + +#include "../common/constants.h" +#include "../common/platform.h" +#include "bit_cost.h" +#include "brotli_bit_stream.h" +#include "entropy_encode.h" +#include "fast_log.h" +#include "find_match_length.h" +#include "hash_base.h" +#include "write_bits.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define MAX_DISTANCE (long)BROTLI_MAX_BACKWARD_LIMIT(18) + +static BROTLI_INLINE uint32_t Hash(const uint8_t* p, + size_t shift, size_t length) { + const uint64_t h = + (BROTLI_UNALIGNED_LOAD64LE(p) << ((8 - length) * 8)) * kHashMul32; + return (uint32_t)(h >> shift); +} + +static BROTLI_INLINE uint32_t HashBytesAtOffset(uint64_t v, size_t offset, + size_t shift, size_t length) { + BROTLI_DCHECK(offset <= 8 - length); + { + const uint64_t h = ((v >> (8 * offset)) << ((8 - length) * 8)) * kHashMul32; + return (uint32_t)(h >> shift); + } +} + +static BROTLI_INLINE BROTLI_BOOL IsMatch(const uint8_t* p1, const uint8_t* p2, + size_t length) { + if (BrotliUnalignedRead32(p1) == BrotliUnalignedRead32(p2)) { + if (length == 4) return BROTLI_TRUE; + return TO_BROTLI_BOOL(p1[4] == p2[4] && p1[5] == p2[5]); + } + return BROTLI_FALSE; +} + +/* Builds a command and distance prefix code (each 64 symbols) into "depth" and + "bits" based on "histogram" and stores it into the bit stream. */ +static void BuildAndStoreCommandPrefixCode(BrotliTwoPassArena* s, + size_t* storage_ix, + uint8_t* storage) { + /* Tree size for building a tree over 64 symbols is 2 * 64 + 1. */ + /* TODO(eustas): initialize once. */ + memset(s->tmp_depth, 0, sizeof(s->tmp_depth)); + BrotliCreateHuffmanTree(s->cmd_histo, 64, 15, s->tmp_tree, s->cmd_depth); + BrotliCreateHuffmanTree(&s->cmd_histo[64], 64, 14, s->tmp_tree, + &s->cmd_depth[64]); + /* We have to jump through a few hoops here in order to compute + the command bits because the symbols are in a different order than in + the full alphabet. This looks complicated, but having the symbols + in this order in the command bits saves a few branches in the Emit* + functions. */ + memcpy(s->tmp_depth, s->cmd_depth + 24, 24); + memcpy(s->tmp_depth + 24, s->cmd_depth, 8); + memcpy(s->tmp_depth + 32, s->cmd_depth + 48, 8); + memcpy(s->tmp_depth + 40, s->cmd_depth + 8, 8); + memcpy(s->tmp_depth + 48, s->cmd_depth + 56, 8); + memcpy(s->tmp_depth + 56, s->cmd_depth + 16, 8); + BrotliConvertBitDepthsToSymbols(s->tmp_depth, 64, s->tmp_bits); + memcpy(s->cmd_bits, s->tmp_bits + 24, 16); + memcpy(s->cmd_bits + 8, s->tmp_bits + 40, 16); + memcpy(s->cmd_bits + 16, s->tmp_bits + 56, 16); + memcpy(s->cmd_bits + 24, s->tmp_bits, 48); + memcpy(s->cmd_bits + 48, s->tmp_bits + 32, 16); + memcpy(s->cmd_bits + 56, s->tmp_bits + 48, 16); + BrotliConvertBitDepthsToSymbols(&s->cmd_depth[64], 64, &s->cmd_bits[64]); + { + /* Create the bit length array for the full command alphabet. */ + size_t i; + memset(s->tmp_depth, 0, 64); /* only 64 first values were used */ + memcpy(s->tmp_depth, s->cmd_depth + 24, 8); + memcpy(s->tmp_depth + 64, s->cmd_depth + 32, 8); + memcpy(s->tmp_depth + 128, s->cmd_depth + 40, 8); + memcpy(s->tmp_depth + 192, s->cmd_depth + 48, 8); + memcpy(s->tmp_depth + 384, s->cmd_depth + 56, 8); + for (i = 0; i < 8; ++i) { + s->tmp_depth[128 + 8 * i] = s->cmd_depth[i]; + s->tmp_depth[256 + 8 * i] = s->cmd_depth[8 + i]; + s->tmp_depth[448 + 8 * i] = s->cmd_depth[16 + i]; + } + BrotliStoreHuffmanTree(s->tmp_depth, BROTLI_NUM_COMMAND_SYMBOLS, + s->tmp_tree, storage_ix, storage); + } + BrotliStoreHuffmanTree(&s->cmd_depth[64], 64, s->tmp_tree, storage_ix, + storage); +} + +static BROTLI_INLINE void EmitInsertLen( + uint32_t insertlen, uint32_t** commands) { + if (insertlen < 6) { + **commands = insertlen; + } else if (insertlen < 130) { + const uint32_t tail = insertlen - 2; + const uint32_t nbits = Log2FloorNonZero(tail) - 1u; + const uint32_t prefix = tail >> nbits; + const uint32_t inscode = (nbits << 1) + prefix + 2; + const uint32_t extra = tail - (prefix << nbits); + **commands = inscode | (extra << 8); + } else if (insertlen < 2114) { + const uint32_t tail = insertlen - 66; + const uint32_t nbits = Log2FloorNonZero(tail); + const uint32_t code = nbits + 10; + const uint32_t extra = tail - (1u << nbits); + **commands = code | (extra << 8); + } else if (insertlen < 6210) { + const uint32_t extra = insertlen - 2114; + **commands = 21 | (extra << 8); + } else if (insertlen < 22594) { + const uint32_t extra = insertlen - 6210; + **commands = 22 | (extra << 8); + } else { + const uint32_t extra = insertlen - 22594; + **commands = 23 | (extra << 8); + } + ++(*commands); +} + +static BROTLI_INLINE void EmitCopyLen(size_t copylen, uint32_t** commands) { + if (copylen < 10) { + **commands = (uint32_t)(copylen + 38); + } else if (copylen < 134) { + const size_t tail = copylen - 6; + const size_t nbits = Log2FloorNonZero(tail) - 1; + const size_t prefix = tail >> nbits; + const size_t code = (nbits << 1) + prefix + 44; + const size_t extra = tail - (prefix << nbits); + **commands = (uint32_t)(code | (extra << 8)); + } else if (copylen < 2118) { + const size_t tail = copylen - 70; + const size_t nbits = Log2FloorNonZero(tail); + const size_t code = nbits + 52; + const size_t extra = tail - ((size_t)1 << nbits); + **commands = (uint32_t)(code | (extra << 8)); + } else { + const size_t extra = copylen - 2118; + **commands = (uint32_t)(63 | (extra << 8)); + } + ++(*commands); +} + +static BROTLI_INLINE void EmitCopyLenLastDistance( + size_t copylen, uint32_t** commands) { + if (copylen < 12) { + **commands = (uint32_t)(copylen + 20); + ++(*commands); + } else if (copylen < 72) { + const size_t tail = copylen - 8; + const size_t nbits = Log2FloorNonZero(tail) - 1; + const size_t prefix = tail >> nbits; + const size_t code = (nbits << 1) + prefix + 28; + const size_t extra = tail - (prefix << nbits); + **commands = (uint32_t)(code | (extra << 8)); + ++(*commands); + } else if (copylen < 136) { + const size_t tail = copylen - 8; + const size_t code = (tail >> 5) + 54; + const size_t extra = tail & 31; + **commands = (uint32_t)(code | (extra << 8)); + ++(*commands); + **commands = 64; + ++(*commands); + } else if (copylen < 2120) { + const size_t tail = copylen - 72; + const size_t nbits = Log2FloorNonZero(tail); + const size_t code = nbits + 52; + const size_t extra = tail - ((size_t)1 << nbits); + **commands = (uint32_t)(code | (extra << 8)); + ++(*commands); + **commands = 64; + ++(*commands); + } else { + const size_t extra = copylen - 2120; + **commands = (uint32_t)(63 | (extra << 8)); + ++(*commands); + **commands = 64; + ++(*commands); + } +} + +static BROTLI_INLINE void EmitDistance(uint32_t distance, uint32_t** commands) { + uint32_t d = distance + 3; + uint32_t nbits = Log2FloorNonZero(d) - 1; + const uint32_t prefix = (d >> nbits) & 1; + const uint32_t offset = (2 + prefix) << nbits; + const uint32_t distcode = 2 * (nbits - 1) + prefix + 80; + uint32_t extra = d - offset; + **commands = distcode | (extra << 8); + ++(*commands); +} + +/* REQUIRES: len <= 1 << 24. */ +static void BrotliStoreMetaBlockHeader( + size_t len, BROTLI_BOOL is_uncompressed, size_t* storage_ix, + uint8_t* storage) { + size_t nibbles = 6; + /* ISLAST */ + BrotliWriteBits(1, 0, storage_ix, storage); + if (len <= (1U << 16)) { + nibbles = 4; + } else if (len <= (1U << 20)) { + nibbles = 5; + } + BrotliWriteBits(2, nibbles - 4, storage_ix, storage); + BrotliWriteBits(nibbles * 4, len - 1, storage_ix, storage); + /* ISUNCOMPRESSED */ + BrotliWriteBits(1, (uint64_t)is_uncompressed, storage_ix, storage); +} + +static BROTLI_INLINE void CreateCommands(const uint8_t* input, + size_t block_size, size_t input_size, const uint8_t* base_ip, int* table, + size_t table_bits, size_t min_match, + uint8_t** literals, uint32_t** commands) { + /* "ip" is the input pointer. */ + const uint8_t* ip = input; + const size_t shift = 64u - table_bits; + const uint8_t* ip_end = input + block_size; + /* "next_emit" is a pointer to the first byte that is not covered by a + previous copy. Bytes between "next_emit" and the start of the next copy or + the end of the input will be emitted as literal bytes. */ + const uint8_t* next_emit = input; + + int last_distance = -1; + const size_t kInputMarginBytes = BROTLI_WINDOW_GAP; + + if (BROTLI_PREDICT_TRUE(block_size >= kInputMarginBytes)) { + /* For the last block, we need to keep a 16 bytes margin so that we can be + sure that all distances are at most window size - 16. + For all other blocks, we only need to keep a margin of 5 bytes so that + we don't go over the block size with a copy. */ + const size_t len_limit = BROTLI_MIN(size_t, block_size - min_match, + input_size - kInputMarginBytes); + const uint8_t* ip_limit = input + len_limit; + + uint32_t next_hash; + for (next_hash = Hash(++ip, shift, min_match); ; ) { + /* Step 1: Scan forward in the input looking for a 6-byte-long match. + If we get close to exhausting the input then goto emit_remainder. + + Heuristic match skipping: If 32 bytes are scanned with no matches + found, start looking only at every other byte. If 32 more bytes are + scanned, look at every third byte, etc.. When a match is found, + immediately go back to looking at every byte. This is a small loss + (~5% performance, ~0.1% density) for compressible data due to more + bookkeeping, but for non-compressible data (such as JPEG) it's a huge + win since the compressor quickly "realizes" the data is incompressible + and doesn't bother looking for matches everywhere. + + The "skip" variable keeps track of how many bytes there are since the + last match; dividing it by 32 (ie. right-shifting by five) gives the + number of bytes to move ahead for each iteration. */ + uint32_t skip = 32; + + const uint8_t* next_ip = ip; + const uint8_t* candidate; + + BROTLI_DCHECK(next_emit < ip); +trawl: + do { + uint32_t hash = next_hash; + uint32_t bytes_between_hash_lookups = skip++ >> 5; + ip = next_ip; + BROTLI_DCHECK(hash == Hash(ip, shift, min_match)); + next_ip = ip + bytes_between_hash_lookups; + if (BROTLI_PREDICT_FALSE(next_ip > ip_limit)) { + goto emit_remainder; + } + next_hash = Hash(next_ip, shift, min_match); + candidate = ip - last_distance; + if (IsMatch(ip, candidate, min_match)) { + if (BROTLI_PREDICT_TRUE(candidate < ip)) { + table[hash] = (int)(ip - base_ip); + break; + } + } + candidate = base_ip + table[hash]; + BROTLI_DCHECK(candidate >= base_ip); + BROTLI_DCHECK(candidate < ip); + + table[hash] = (int)(ip - base_ip); + } while (BROTLI_PREDICT_TRUE(!IsMatch(ip, candidate, min_match))); + + /* Check copy distance. If candidate is not feasible, continue search. + Checking is done outside of hot loop to reduce overhead. */ + if (ip - candidate > MAX_DISTANCE) goto trawl; + + /* Step 2: Emit the found match together with the literal bytes from + "next_emit", and then see if we can find a next match immediately + afterwards. Repeat until we find no match for the input + without emitting some literal bytes. */ + + { + /* We have a 6-byte match at ip, and we need to emit bytes in + [next_emit, ip). */ + const uint8_t* base = ip; + size_t matched = min_match + FindMatchLengthWithLimit( + candidate + min_match, ip + min_match, + (size_t)(ip_end - ip) - min_match); + int distance = (int)(base - candidate); /* > 0 */ + int insert = (int)(base - next_emit); + ip += matched; + BROTLI_DCHECK(0 == memcmp(base, candidate, matched)); + EmitInsertLen((uint32_t)insert, commands); + BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n", + (int)(next_emit - base_ip), insert, 2)); + memcpy(*literals, next_emit, (size_t)insert); + *literals += insert; + if (distance == last_distance) { + **commands = 64; + ++(*commands); + } else { + EmitDistance((uint32_t)distance, commands); + last_distance = distance; + } + EmitCopyLenLastDistance(matched, commands); + BROTLI_LOG(("[CompressFragment] pos = %d distance = %d\n" + "[CompressFragment] pos = %d insert = %d copy = %d\n" + "[CompressFragment] pos = %d distance = %d\n", + (int)(base - base_ip), (int)distance, + (int)(base - base_ip) + 2, 0, (int)matched - 2, + (int)(base - base_ip) + 2, (int)distance)); + + next_emit = ip; + if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) { + goto emit_remainder; + } + { + /* We could immediately start working at ip now, but to improve + compression we first update "table" with the hashes of some + positions within the last copy. */ + uint64_t input_bytes; + uint32_t cur_hash; + uint32_t prev_hash; + if (min_match == 4) { + input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3); + cur_hash = HashBytesAtOffset(input_bytes, 3, shift, min_match); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 3); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 1); + } else { + input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 5); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 4); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 3); + input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2); + cur_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 1); + } + + candidate = base_ip + table[cur_hash]; + table[cur_hash] = (int)(ip - base_ip); + } + } + + while (ip - candidate <= MAX_DISTANCE && + IsMatch(ip, candidate, min_match)) { + /* We have a 6-byte match at ip, and no need to emit any + literal bytes prior to ip. */ + const uint8_t* base = ip; + size_t matched = min_match + FindMatchLengthWithLimit( + candidate + min_match, ip + min_match, + (size_t)(ip_end - ip) - min_match); + ip += matched; + last_distance = (int)(base - candidate); /* > 0 */ + BROTLI_DCHECK(0 == memcmp(base, candidate, matched)); + EmitCopyLen(matched, commands); + EmitDistance((uint32_t)last_distance, commands); + BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n" + "[CompressFragment] pos = %d distance = %d\n", + (int)(base - base_ip), 0, (int)matched, + (int)(base - base_ip), (int)last_distance)); + + next_emit = ip; + if (BROTLI_PREDICT_FALSE(ip >= ip_limit)) { + goto emit_remainder; + } + { + /* We could immediately start working at ip now, but to improve + compression we first update "table" with the hashes of some + positions within the last copy. */ + uint64_t input_bytes; + uint32_t cur_hash; + uint32_t prev_hash; + if (min_match == 4) { + input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 3); + cur_hash = HashBytesAtOffset(input_bytes, 3, shift, min_match); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 3); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 1); + } else { + input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 5); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 5); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 4); + prev_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 3); + input_bytes = BROTLI_UNALIGNED_LOAD64LE(ip - 2); + cur_hash = HashBytesAtOffset(input_bytes, 2, shift, min_match); + prev_hash = HashBytesAtOffset(input_bytes, 0, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 2); + prev_hash = HashBytesAtOffset(input_bytes, 1, shift, min_match); + table[prev_hash] = (int)(ip - base_ip - 1); + } + + candidate = base_ip + table[cur_hash]; + table[cur_hash] = (int)(ip - base_ip); + } + } + + next_hash = Hash(++ip, shift, min_match); + } + } + +emit_remainder: + BROTLI_DCHECK(next_emit <= ip_end); + /* Emit the remaining bytes as literals. */ + if (next_emit < ip_end) { + const uint32_t insert = (uint32_t)(ip_end - next_emit); + EmitInsertLen(insert, commands); + BROTLI_LOG(("[CompressFragment] pos = %d insert = %d copy = %d\n", + (int)(next_emit - base_ip), insert, 2)); + memcpy(*literals, next_emit, insert); + *literals += insert; + } +} + +static void StoreCommands(BrotliTwoPassArena* s, + const uint8_t* literals, const size_t num_literals, + const uint32_t* commands, const size_t num_commands, + size_t* storage_ix, uint8_t* storage) { + static const BROTLI_MODEL("small") uint32_t kNumExtraBits[128] = { + 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, + 6, 7, 8, 9, 10, 12, 14, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 2, 2, 3, 3, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, + 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, + }; + static const BROTLI_MODEL("small") uint32_t kInsertOffset[24] = { + 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, + 34, 50, 66, 98, 130, 194, 322, 578, 1090, 2114, 6210, 22594, + }; + + size_t i; + memset(s->lit_histo, 0, sizeof(s->lit_histo)); + /* TODO(eustas): is that necessary? */ + memset(s->cmd_depth, 0, sizeof(s->cmd_depth)); + /* TODO(eustas): is that necessary? */ + memset(s->cmd_bits, 0, sizeof(s->cmd_bits)); + memset(s->cmd_histo, 0, sizeof(s->cmd_histo)); + for (i = 0; i < num_literals; ++i) { + ++s->lit_histo[literals[i]]; + } + BrotliBuildAndStoreHuffmanTreeFast(s->tmp_tree, s->lit_histo, num_literals, + /* max_bits = */ 8, s->lit_depth, + s->lit_bits, storage_ix, storage); + + for (i = 0; i < num_commands; ++i) { + const uint32_t code = commands[i] & 0xFF; + BROTLI_DCHECK(code < 128); + ++s->cmd_histo[code]; + } + s->cmd_histo[1] += 1; + s->cmd_histo[2] += 1; + s->cmd_histo[64] += 1; + s->cmd_histo[84] += 1; + BuildAndStoreCommandPrefixCode(s, storage_ix, storage); + + for (i = 0; i < num_commands; ++i) { + const uint32_t cmd = commands[i]; + const uint32_t code = cmd & 0xFF; + const uint32_t extra = cmd >> 8; + BROTLI_DCHECK(code < 128); + BrotliWriteBits(s->cmd_depth[code], s->cmd_bits[code], storage_ix, storage); + BrotliWriteBits(kNumExtraBits[code], extra, storage_ix, storage); + if (code < 24) { + const uint32_t insert = kInsertOffset[code] + extra; + uint32_t j; + for (j = 0; j < insert; ++j) { + const uint8_t lit = *literals; + BrotliWriteBits(s->lit_depth[lit], s->lit_bits[lit], storage_ix, + storage); + ++literals; + } + } + } +} + +/* Acceptable loss for uncompressible speedup is 2% */ +#define MIN_RATIO 0.98 +#define SAMPLE_RATE 43 + +static BROTLI_BOOL ShouldCompress(BrotliTwoPassArena* s, + const uint8_t* input, size_t input_size, size_t num_literals) { + double corpus_size = (double)input_size; + if ((double)num_literals < MIN_RATIO * corpus_size) { + return BROTLI_TRUE; + } else { + const double max_total_bit_cost = corpus_size * 8 * MIN_RATIO / SAMPLE_RATE; + size_t i; + memset(s->lit_histo, 0, sizeof(s->lit_histo)); + for (i = 0; i < input_size; i += SAMPLE_RATE) { + ++s->lit_histo[input[i]]; + } + return TO_BROTLI_BOOL( + BrotliBitsEntropy(s->lit_histo, 256) < max_total_bit_cost); + } +} + +static void RewindBitPosition(const size_t new_storage_ix, + size_t* storage_ix, uint8_t* storage) { + const size_t bitpos = new_storage_ix & 7; + const size_t mask = (1u << bitpos) - 1; + storage[new_storage_ix >> 3] &= (uint8_t)mask; + *storage_ix = new_storage_ix; +} + +static void EmitUncompressedMetaBlock(const uint8_t* input, size_t input_size, + size_t* storage_ix, uint8_t* storage) { + BrotliStoreMetaBlockHeader(input_size, 1, storage_ix, storage); + *storage_ix = (*storage_ix + 7u) & ~7u; + memcpy(&storage[*storage_ix >> 3], input, input_size); + *storage_ix += input_size << 3; + storage[*storage_ix >> 3] = 0; +} + +static BROTLI_INLINE void BrotliCompressFragmentTwoPassImpl( + BrotliTwoPassArena* s, const uint8_t* input, size_t input_size, + BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf, + int* table, size_t table_bits, size_t min_match, + size_t* storage_ix, uint8_t* storage) { + /* Save the start of the first block for position and distance computations. + */ + const uint8_t* base_ip = input; + BROTLI_UNUSED(is_last); + + while (input_size > 0) { + size_t block_size = + BROTLI_MIN(size_t, input_size, kCompressFragmentTwoPassBlockSize); + uint32_t* commands = command_buf; + uint8_t* literals = literal_buf; + size_t num_literals; + CreateCommands(input, block_size, input_size, base_ip, table, + table_bits, min_match, &literals, &commands); + num_literals = (size_t)(literals - literal_buf); + if (ShouldCompress(s, input, block_size, num_literals)) { + const size_t num_commands = (size_t)(commands - command_buf); + BrotliStoreMetaBlockHeader(block_size, 0, storage_ix, storage); + /* No block splits, no contexts. */ + BrotliWriteBits(13, 0, storage_ix, storage); + StoreCommands(s, literal_buf, num_literals, command_buf, num_commands, + storage_ix, storage); + } else { + /* Since we did not find many backward references and the entropy of + the data is close to 8 bits, we can simply emit an uncompressed block. + This makes compression speed of uncompressible data about 3x faster. */ + EmitUncompressedMetaBlock(input, block_size, storage_ix, storage); + } + input += block_size; + input_size -= block_size; + } +} + +#define FOR_TABLE_BITS_(X) \ + X(8) X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16) X(17) + +#define BAKE_METHOD_PARAM_(B) \ +static BROTLI_NOINLINE void BrotliCompressFragmentTwoPassImpl ## B( \ + BrotliTwoPassArena* s, const uint8_t* input, size_t input_size, \ + BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf, \ + int* table, size_t* storage_ix, uint8_t* storage) { \ + size_t min_match = (B <= 15) ? 4 : 6; \ + BrotliCompressFragmentTwoPassImpl(s, input, input_size, is_last, command_buf,\ + literal_buf, table, B, min_match, storage_ix, storage); \ +} +FOR_TABLE_BITS_(BAKE_METHOD_PARAM_) +#undef BAKE_METHOD_PARAM_ + +void BrotliCompressFragmentTwoPass( + BrotliTwoPassArena* s, const uint8_t* input, size_t input_size, + BROTLI_BOOL is_last, uint32_t* command_buf, uint8_t* literal_buf, + int* table, size_t table_size, size_t* storage_ix, uint8_t* storage) { + const size_t initial_storage_ix = *storage_ix; + const size_t table_bits = Log2FloorNonZero(table_size); + switch (table_bits) { +#define CASE_(B) \ + case B: \ + BrotliCompressFragmentTwoPassImpl ## B( \ + s, input, input_size, is_last, command_buf, \ + literal_buf, table, storage_ix, storage); \ + break; + FOR_TABLE_BITS_(CASE_) +#undef CASE_ + default: BROTLI_DCHECK(0); break; + } + + /* If output is larger than single uncompressed block, rewrite it. */ + if (*storage_ix - initial_storage_ix > 31 + (input_size << 3)) { + RewindBitPosition(initial_storage_ix, storage_ix, storage); + EmitUncompressedMetaBlock(input, input_size, storage_ix, storage); + } + + if (is_last) { + BrotliWriteBits(1, 1, storage_ix, storage); /* islast */ + BrotliWriteBits(1, 1, storage_ix, storage); /* isempty */ + *storage_ix = (*storage_ix + 7u) & ~7u; + } +} + +#undef FOR_TABLE_BITS_ + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/compress_fragment_two_pass.h b/packages/runtime/vendor/brotli/c/enc/compress_fragment_two_pass.h new file mode 100644 index 000000000..e98b5e0e2 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/compress_fragment_two_pass.h @@ -0,0 +1,70 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function for fast encoding of an input fragment, independently from the input + history. This function uses two-pass processing: in the first pass we save + the found backward matches and literal bytes into a buffer, and in the + second pass we emit them into the bit stream using prefix codes built based + on the actual command and literal byte histograms. */ + +#ifndef BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ +#define BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ + +#include "../common/constants.h" +#include "../common/platform.h" +#include "entropy_encode.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* TODO(eustas): turn to macro. */ +static const size_t kCompressFragmentTwoPassBlockSize = 1 << 17; + +typedef struct BrotliTwoPassArena { + uint32_t lit_histo[256]; + uint8_t lit_depth[256]; + uint16_t lit_bits[256]; + + uint32_t cmd_histo[128]; + uint8_t cmd_depth[128]; + uint16_t cmd_bits[128]; + + /* BuildAndStoreCommandPrefixCode */ + HuffmanTree tmp_tree[2 * BROTLI_NUM_LITERAL_SYMBOLS + 1]; + uint8_t tmp_depth[BROTLI_NUM_COMMAND_SYMBOLS]; + uint16_t tmp_bits[64]; +} BrotliTwoPassArena; + +/* Compresses "input" string to the "*storage" buffer as one or more complete + meta-blocks, and updates the "*storage_ix" bit position. + + If "is_last" is 1, emits an additional empty last meta-block. + + REQUIRES: "input_size" is greater than zero, or "is_last" is 1. + REQUIRES: "input_size" is less or equal to maximal metablock size (1 << 24). + REQUIRES: "command_buf" and "literal_buf" point to at least + kCompressFragmentTwoPassBlockSize long arrays. + REQUIRES: All elements in "table[0..table_size-1]" are initialized to zero. + REQUIRES: "table_size" is a power of two + OUTPUT: maximal copy distance <= |input_size| + OUTPUT: maximal copy distance <= BROTLI_MAX_BACKWARD_LIMIT(18) */ +BROTLI_INTERNAL void BrotliCompressFragmentTwoPass(BrotliTwoPassArena* s, + const uint8_t* input, + size_t input_size, + BROTLI_BOOL is_last, + uint32_t* command_buf, + uint8_t* literal_buf, + int* table, + size_t table_size, + size_t* storage_ix, + uint8_t* storage); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/dictionary_hash.c b/packages/runtime/vendor/brotli/c/enc/dictionary_hash.c new file mode 100644 index 000000000..193f7a41c --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/dictionary_hash.c @@ -0,0 +1,145 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Hash table on the 4-byte prefixes of static dictionary words. */ + +#include "dictionary_hash.h" + +#include "../common/platform.h" /* IWYU pragma: keep */ +#include "../common/static_init.h" + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +#include "../common/dictionary.h" +#include "hash_base.h" +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +BROTLI_BOOL BROTLI_COLD BrotliEncoderInitDictionaryHash( + const BrotliDictionary* dict, uint16_t* words, uint8_t* lengths) { + size_t global_idx = 0; + size_t len; + size_t i; + static const uint8_t frozen_idx[1688] = {0, 0, 8, 164, 32, 56, 31, 191, 36, 4, +128, 81, 68, 132, 145, 129, 0, 0, 0, 28, 0, 8, 1, 1, 64, 3, 1, 0, 0, 0, 0, 0, 4, +64, 1, 2, 128, 0, 132, 49, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 1, 0, 36, 152, +0, 0, 0, 0, 128, 8, 0, 0, 128, 0, 0, 8, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, +0, 0, 0, 1, 0, 64, 133, 0, 32, 0, 0, 128, 1, 0, 0, 0, 0, 4, 4, 4, 32, 16, 130, +0, 128, 8, 0, 0, 0, 0, 0, 64, 0, 64, 0, 160, 0, 148, 53, 0, 0, 0, 0, 0, 128, 0, +130, 0, 0, 0, 8, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 32, 1, 32, 129, 0, 12, 0, +1, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, +0, 0, 2, 0, 0, 0, 0, 0, 32, 0, 0, 0, 2, 66, 128, 0, 0, 16, 0, 0, 0, 0, 64, 1, 6, +128, 8, 0, 192, 24, 32, 0, 0, 8, 4, 128, 128, 2, 160, 0, 160, 0, 64, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 0, 0, 32, 1, 0, 0, 64, 0, 0, 0, 0, 0, 0, 32, 0, 66, 0, 2, 0, +4, 0, 8, 0, 2, 0, 0, 33, 8, 0, 0, 0, 8, 0, 128, 162, 4, 128, 0, 2, 33, 0, 160, +0, 8, 0, 64, 0, 160, 0, 129, 4, 0, 0, 32, 0, 0, 32, 0, 2, 0, 0, 0, 0, 0, 0, 128, +0, 0, 0, 0, 0, 64, 10, 0, 0, 0, 0, 32, 64, 0, 0, 0, 0, 0, 16, 0, 16, 16, 0, 0, +80, 2, 0, 0, 0, 0, 8, 0, 0, 16, 0, 8, 0, 0, 0, 8, 64, 128, 0, 0, 0, 8, 208, 0, +0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 32, 0, 8, 0, 128, 0, 0, 0, 1, 0, 0, 0, +16, 8, 1, 136, 0, 0, 36, 0, 64, 9, 0, 1, 32, 8, 0, 64, 64, 131, 16, 224, 32, 4, +0, 4, 5, 160, 0, 131, 0, 4, 96, 0, 0, 184, 192, 0, 177, 205, 96, 0, 0, 0, 0, 2, +0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 128, 0, 0, 8, 0, 0, 0, 0, 1, 4, 0, 1, +0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 4, 0, 0, 64, 69, 0, 0, 8, 2, 66, 32, 64, 0, 0, 0, +0, 0, 1, 0, 128, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 16, 0, 0, 4, 128, 64, +0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 8, 0, 0, 130, 16, 64, 128, 2, 64, 0, 0, 0, 128, +2, 192, 64, 0, 65, 0, 0, 0, 16, 0, 0, 0, 32, 4, 2, 2, 76, 0, 0, 0, 4, 72, 52, +131, 44, 76, 0, 0, 0, 0, 64, 1, 16, 148, 4, 0, 16, 10, 64, 0, 2, 0, 1, 0, 128, +64, 68, 0, 0, 0, 0, 0, 64, 144, 0, 8, 0, 2, 0, 0, 0, 0, 0, 0, 3, 64, 0, 0, 0, 0, +1, 128, 0, 0, 32, 66, 0, 0, 0, 40, 0, 18, 0, 0, 0, 0, 0, 33, 0, 0, 32, 0, 0, 32, +0, 128, 4, 64, 145, 140, 0, 0, 0, 128, 0, 2, 0, 0, 20, 0, 80, 38, 0, 0, 32, 0, +32, 64, 4, 4, 0, 4, 0, 0, 0, 129, 4, 0, 0, 144, 17, 32, 130, 16, 132, 24, 134, +0, 0, 64, 2, 5, 50, 8, 194, 33, 1, 68, 117, 1, 8, 32, 161, 54, 0, 130, 34, 0, 0, +0, 64, 128, 0, 0, 2, 0, 0, 0, 0, 32, 1, 0, 0, 0, 3, 14, 0, 0, 0, 0, 0, 16, 4, 0, +0, 0, 0, 0, 0, 0, 0, 96, 1, 24, 18, 0, 1, 128, 24, 0, 64, 0, 4, 0, 16, 128, 0, +64, 0, 0, 0, 64, 0, 8, 0, 0, 0, 0, 0, 66, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 16, 0, 64, 2, 0, 0, 0, 0, 6, 0, 8, 8, 2, 0, 64, 0, 0, 0, 0, 128, 2, +2, 12, 64, 0, 64, 0, 8, 0, 128, 32, 0, 0, 10, 0, 0, 32, 0, 128, 32, 33, 8, 136, +0, 96, 64, 0, 0, 0, 0, 0, 64, 4, 16, 4, 8, 0, 0, 0, 16, 0, 2, 0, 0, 1, 128, 0, +64, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 2, 0, 16, 0, 4, 0, 8, 0, 0, 0, 0, 0, +20, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 136, 0, 0, 0, 0, 0, 8, 0, +0, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, +0, 0, 4, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 2, 128, 0, 0, 0, 8, 2, 0, 0, 128, 0, 16, 2, 0, 0, 4, 0, 32, 0, 0, 1, +4, 64, 64, 0, 4, 0, 1, 0, 16, 0, 32, 68, 4, 4, 65, 10, 0, 20, 37, 18, 1, 148, 0, +32, 128, 3, 8, 0, 64, 0, 0, 0, 0, 0, 0, 4, 0, 16, 1, 128, 0, 0, 0, 128, 16, 0, +0, 0, 0, 1, 128, 0, 0, 128, 64, 128, 64, 0, 130, 0, 164, 8, 0, 0, 1, 64, 128, 0, +18, 0, 2, 150, 0, 8, 0, 0, 64, 0, 81, 0, 0, 16, 128, 2, 8, 36, 32, 129, 4, 144, +13, 0, 0, 3, 8, 1, 0, 2, 0, 0, 64, 0, 5, 0, 1, 34, 1, 32, 2, 16, 128, 128, 128, +0, 0, 0, 2, 0, 4, 18, 8, 12, 34, 32, 192, 6, 64, 224, 33, 0, 0, 137, 72, 64, 0, +24, 8, 128, 128, 0, 16, 0, 32, 128, 128, 132, 8, 0, 0, 16, 0, 64, 0, 0, 4, 0, 0, +16, 0, 4, 128, 64, 0, 0, 1, 0, 4, 64, 32, 144, 130, 2, 128, 0, 192, 0, 64, 82, +64, 1, 32, 128, 128, 2, 0, 84, 0, 32, 0, 44, 24, 72, 80, 32, 16, 0, 0, 44, 16, +96, 64, 1, 72, 131, 0, 0, 0, 16, 0, 0, 165, 0, 129, 2, 49, 48, 64, 64, 12, 64, +176, 64, 84, 8, 128, 20, 64, 213, 136, 104, 1, 41, 15, 83, 170, 0, 0, 41, 1, 64, +64, 0, 193, 64, 64, 8, 0, 128, 0, 0, 64, 8, 64, 8, 1, 16, 0, 8, 0, 0, 2, 1, 128, +28, 84, 141, 97, 0, 0, 68, 0, 0, 129, 8, 0, 16, 8, 32, 0, 64, 0, 0, 0, 24, 0, 0, +0, 192, 0, 8, 128, 0, 0, 0, 0, 0, 64, 0, 1, 0, 0, 0, 0, 40, 1, 128, 64, 0, 4, 2, +32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 32, 8, 0, 32, 0, 0, 0, 16, 17, 0, +2, 4, 0, 0, 33, 128, 2, 0, 0, 0, 0, 129, 0, 2, 0, 0, 0, 36, 0, 32, 2, 0, 0, 0, +0, 0, 0, 32, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 32, 64, 0, 0, 0, 0, 0, 0, +32, 0, 0, 32, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 16, 0, 0, 0, 0, 0, 0, 0, +1, 0, 136, 0, 0, 24, 192, 128, 3, 0, 17, 18, 2, 0, 66, 0, 4, 24, 0, 9, 208, 167, +0, 144, 20, 64, 0, 130, 64, 0, 2, 16, 136, 8, 74, 32, 0, 168, 0, 65, 32, 8, 12, +1, 3, 1, 64, 180, 3, 0, 64, 0, 8, 0, 0, 32, 65, 0, 4, 16, 4, 16, 68, 32, 64, 36, +32, 24, 33, 1, 128, 0, 0, 8, 0, 32, 64, 81, 0, 1, 10, 19, 8, 0, 0, 4, 5, 144, 0, +0, 8, 128, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 80, 1, 0, 0, +33, 0, 32, 66, 4, 2, 0, 1, 43, 2, 0, 0, 4, 32, 16, 0, 64, 0, 3, 32, 0, 2, 64, +64, 116, 0, 65, 52, 64, 0, 17, 64, 192, 96, 8, 10, 8, 2, 4, 0, 17, 64, 0, 4, 0, +0, 4, 128, 0, 0, 9, 0, 0, 130, 2, 0, 192, 0, 48, 128, 64, 0, 96, 0, 64, 0, 1, +16, 32, 0, 1, 32, 6, 128, 2, 32, 0, 12, 0, 0, 48, 32, 8, 0, 0, 128, 0, 18, 0, +0, 28, 24, 41, 16, 5, 32, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 0, 0, 0, 8, 0, 0, 0, 0, 16, 128, +0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 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}; + + memset(lengths, 0, BROTLI_ENC_NUM_HASH_BUCKETS); + + for (len = BROTLI_MAX_DICTIONARY_WORD_LENGTH; + len >= BROTLI_MIN_DICTIONARY_WORD_LENGTH; --len) { + size_t length_lt_8 = len < 8 ? 1 : 0; + size_t n = 1u << dict->size_bits_by_length[len]; + const uint8_t* dict_words = dict->data + dict->offsets_by_length[len]; + for (i = 0; i < n; ++i) { + size_t j = n - 1 - i; + const uint8_t* word = dict_words + len * j; + const uint32_t key = Hash14(word); + size_t idx = (key << 1) + length_lt_8; + if ((lengths[idx] & 0x80) == 0) { + BROTLI_BOOL is_final = TO_BROTLI_BOOL(frozen_idx[global_idx / 8] & + (1u << (global_idx % 8))); + words[idx] = (uint16_t)j; + lengths[idx] = (uint8_t)(len + (is_final ? 0x80 : 0)); + } + global_idx++; + } + } + for (i = 0; i < BROTLI_ENC_NUM_HASH_BUCKETS; ++i) { + lengths[i] &= 0x7F; + } + + return BROTLI_TRUE; +} + +BROTLI_MODEL("small") +uint16_t kStaticDictionaryHashWords[BROTLI_ENC_NUM_HASH_BUCKETS]; +BROTLI_MODEL("small") +uint8_t kStaticDictionaryHashLengths[BROTLI_ENC_NUM_HASH_BUCKETS]; + +#else /* BROTLI_STATIC_INIT */ + +/* Embed kStaticDictionaryHashWords and kStaticDictionaryHashLengths. */ +#include "dictionary_hash_inc.h" + +#endif /* BROTLI_STATIC_INIT */ + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/dictionary_hash.h b/packages/runtime/vendor/brotli/c/enc/dictionary_hash.h new file mode 100644 index 000000000..dfddc017d --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/dictionary_hash.h @@ -0,0 +1,45 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Hash table on the 4-byte prefixes of static dictionary words. */ + +#ifndef BROTLI_ENC_DICTIONARY_HASH_H_ +#define BROTLI_ENC_DICTIONARY_HASH_H_ + +#include "../common/platform.h" +#include "../common/static_init.h" + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +#include "../common/dictionary.h" +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Bucket is (Hash14 * 2 + length_lt_8); in other words we reserve 2 buckets + for each hash - one for shorter words and one for longer words. */ +#define BROTLI_ENC_NUM_HASH_BUCKETS 32768 + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +BROTLI_BOOL BROTLI_INTERNAL BrotliEncoderInitDictionaryHash( + const BrotliDictionary* dictionary, uint16_t* words, uint8_t* lengths); +BROTLI_INTERNAL extern BROTLI_MODEL("small") uint16_t + kStaticDictionaryHashWords[BROTLI_ENC_NUM_HASH_BUCKETS]; +BROTLI_INTERNAL extern BROTLI_MODEL("small") uint8_t + kStaticDictionaryHashLengths[BROTLI_ENC_NUM_HASH_BUCKETS]; +#else +BROTLI_INTERNAL extern const BROTLI_MODEL("small") uint16_t + kStaticDictionaryHashWords[BROTLI_ENC_NUM_HASH_BUCKETS]; +BROTLI_INTERNAL extern const BROTLI_MODEL("small") uint8_t + kStaticDictionaryHashLengths[BROTLI_ENC_NUM_HASH_BUCKETS]; +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_DICTIONARY_HASH_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/dictionary_hash_inc.h b/packages/runtime/vendor/brotli/c/enc/dictionary_hash_inc.h new file mode 100644 index 000000000..89e04f0f4 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/dictionary_hash_inc.h @@ -0,0 +1,1829 @@ +const BROTLI_MODEL("small") +uint16_t kStaticDictionaryHashWords[BROTLI_ENC_NUM_HASH_BUCKETS] = { +1002,0,0,0,0,0,0,0,0,683,0,0,0,0,0,0,0,1265,0,0,0,0,0,1431,0,0,0,0,0,0,40,0,0,0, +0,155,8,741,0,624,0,0,0,0,0,0,0,0,0,0,0,0,66,503,0,0,0,451,0,0,0,0,0,0,0,835,70, +0,0,539,0,0,0,0,0,0,0,0,0,113,0,0,0,0,718,0,0,0,0,0,0,520,0,1070,0,0,0,0,0,1515, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,78,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,610,0,0,750,0,0,0,307,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,964,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,999,0,0,0,0,0,0,0,0, +645,75,0,649,52,282,0,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1621,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,211,225,0,0,687,718,0,0,110,0,58,0,0,0,0,0,0,345,0,0,301,0,0, +0,203,0,0,1154,674,1949,0,0,0,0,0,0,0,0,0,259,0,0,0,0,0,0,0,1275,0,0,0,1231,254, +0,0,0,0,0,0,0,277,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,800,0,0,0,29, +116,100,490,0,0,0,0,0,1641,0,543,0,0,0,0,41,181,0,657,0,0,202,25,0,0,0,0,0,0,0, +0,0,0,423,0,0,0,113,0,0,0,927,963,0,976,0,206,0,0,0,0,0,0,0,0,0,2002,0,0,0,0,0, +0,0,0,0,0,0,696,0,1170,0,0,0,0,226,13,0,769,678,551,0,0,0,0,0,0,57,0,0,0,10,188, +0,0,0,624,0,0,0,0,0,0,0,0,0,1941,130,0,0,0,0,378,269,0,0,528,0,1146,0,0,0,1105, +0,1616,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,656,0,1940,0,0,0,0,0,173,0,0,0,0,0,0,0,0,0, +0,0,457,342,810,0,0,0,0,620,0,0,0,0,0,0,0,967,95,447,406,0,0,0,477,0,1268,944, +1941,0,0,0,629,0,0,0,0,0,375,0,0,0,1636,0,0,0,0,774,0,1,1034,0,0,0,0,0,824,0,0, +0,0,0,118,0,0,560,296,0,0,0,0,0,0,0,0,1009,894,0,0,0,0,0,0,0,0,0,0,0,0,0,1474, +366,0,0,0,0,0,0,0,0,0,79,1723,0,0,200,0,0,0,0,0,0,0,0,1759,372,0,16,0,943,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,258,0,0,900,1839,707,30,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2004,0,0,10,115,0,50,0,0,0,0,0,0,0,0,0,0,520,1,0,738,98,482,0,0,0,0, +0,0,0,0,0,0,701,2,0,0,0,0,0,0,0,0,557,0,0,0,0,0,0,0,0,0,347,0,0,0,0,572,0,0,0,0, +0,0,0,0,0,832,0,0,797,809,0,0,0,0,0,0,0,0,0,0,0,528,0,0,0,861,0,0,294,0,0,0,109, +0,0,0,0,0,0,0,0,1187,290,266,0,0,0,0,49,50,748,0,0,466,399,0,0,0,0,0,0,0,378,0, +519,0,0,0,0,0,0,0,0,0,0,0,0,667,351,902,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,180, +0,0,869,0,0,0,0,0,0,0,260,0,0,0,0,0,0,0,0,0,0,523,36,0,0,587,510,809,29,260,0,0, +0,0,0,0,0,0,570,0,565,0,1464,0,0,0,0,0,0,10,0,0,787,399,380,200,0,0,0,0,516,0, +844,887,0,0,0,0,0,0,0,44,0,0,0,305,1655,0,0,0,0,0,0,0,0,0,0,0,0,0,0,786,10,0,0, +0,0,0,0,0,0,0,2031,0,0,0,0,0,684,0,0,0,0,0,1480,0,0,0,27,0,0,0,395,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,813,511,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,206, +496,0,0,0,0,0,909,0,891,0,0,0,0,0,0,0,0,0,687,0,0,0,1342,0,0,0,0,0,0,0,0,0,0, +160,41,0,0,0,0,0,0,0,0,0,0,0,1718,778,0,0,0,0,0,0,0,0,0,0,1610,0,0,0,0,0,115,0, +0,0,0,314,294,0,0,0,983,178,193,0,0,0,0,0,0,0,0,0,174,0,0,0,0,0,0,0,0,0,0,848, +1796,0,0,0,0,0,0,221,0,687,1660,0,0,0,0,262,0,0,179,0,0,0,0,0,66,0,773,0,352,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,152,0,0,1197,0,0,0,0,0,0,0,0,0,0,0,0,560,0,0, +564,0,0,0,797,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,556,0,819,0,0,0,0,0,0,0,0,719,544, +637,5,0,0,0,0,0,0,0,0,0,0,0,101,0,1441,0,0,0,893,0,0,0,0,0,0,0,0,0,238,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1296,0,0,969,1729,314,60,0,0,0,0,0,1144,0,1147,0,0,0,0,0, +0,0,0,0,0,437,1853,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,828,0,176,0,0,0,0,0,0,434,39,0, +0,0,0,0,159,0,0,0,902,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,270,0,0,0,0,801,556,0,0, +0,0,0,0,0,416,19,197,369,0,0,0,0,0,0,0,0,0,28,34,0,757,0,0,898,1553,0,721,0,0,0, +0,1012,0,0,0,0,1102,0,898,183,0,0,0,0,0,0,0,136,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,247,277,0,0,0,435,0,0,0,0,0,1311,0,0,0,0, +0,0,211,437,0,0,0,28,0,0,750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2012,0,702, +0,808,0,0,0,0,739,166,0,0,0,0,0,0,719,170,500,0,0,0,0,0,0,0,0,1500,327,0,0,450, +0,0,0,1318,0,0,0,1602,0,0,331,754,0,0,0,0,0,1368,0,0,557,0,0,0,799,850,0,0,0,0, +0,0,0,0,908,0,0,0,0,0,19,62,459,0,0,0,0,0,0,0,0,0,0,0,0,1802,0,0,0,0,0,0,0,0,0, +1397,0,0,0,0,120,238,0,0,0,0,0,0,0,0,0,0,0,1324,0,0,0,0,0,0,0,0,602,201,0,0,164, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,615,0,0,0,0,0,0,0,0,0,0,0,0,0,1243,0,0,0,0,968,0,0, +0,0,0,0,882,0,0,0,907,329,100,0,0,0,0,0,0,0,0,0,0,0,176,26,9,0,0,265,256,0,0,0, +0,0,0,0,0,0,643,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,610,0,0,0,0,973,2001,0, +0,0,0,0,0,522,0,0,0,0,0,0,0,0,0,0,0,553,0,0,0,0,0,0,1582,0,1578,0,0,0,0,0,0,0,0, +0,0,0,795,0,0,0,432,0,0,0,0,0,0,84,126,0,0,0,0,790,0,377,64,0,1529,0,0,0,0,530, +1857,539,1104,0,0,0,0,0,0,0,0,0,0,0,0,977,0,0,0,34,0,0,0,0,0,0,0,0,0,0,0,24,26, +0,0,918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,379,0,0,0,0,0,0,0,792, +0,0,0,0,0,0,0,0,0,1920,0,0,0,0,0,0,0,0,0,771,0,0,0,1979,0,901,254,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,140,0,0,0,0,0,440,37,0, +508,0,0,0,513,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,8,0,0,533,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,752,920,0,1048,0,153,0, +0,391,0,0,1952,0,0,0,0,0,0,0,0,0,0,126,0,0,0,0,640,0,483,69,1616,0,0,0,0,0,734, +0,0,0,0,0,0,480,0,495,0,472,0,0,0,0,0,0,0,0,874,229,0,0,0,0,948,0,0,0,0,0,0,0,0, +1009,748,0,555,0,0,0,0,0,0,193,0,653,0,0,0,0,0,0,0,0,0,0,984,0,0,0,172,0,0,0,0, +0,0,0,0,83,1568,0,0,384,0,0,0,0,0,0,0,164,880,0,0,0,0,0,0,0,0,0,0,0,367,121,0,0, +828,0,0,0,0,0,0,0,1541,0,0,0,0,0,0,0,343,0,0,0,0,0,0,0,0,561,57,0,0,0,0,0,0,0, +926,0,0,0,0,827,0,194,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,0,0,0,0,0,0, +0,0,0,896,1249,0,0,0,0,0,1614,0,0,0,860,0,0,0,0,0,0,0,0,964,102,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,899,0,569,0,0,0,0,795,2045,0,0,0, +0,0,0,104,52,0,0,0,0,0,604,0,0,0,0,779,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0, +494,0,677,0,0,0,0,0,0,0,508,0,0,0,0,0,0,0,0,0,1014,0,957,0,0,630,310,0,0,0,570, +0,0,449,0,64,537,0,0,0,0,0,0,0,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,702,1650,49,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,1279,0,0,0,0,0,0,0,896,0,0, +178,0,0,0,0,0,0,0,0,0,0,0,0,0,808,695,0,0,0,0,539,1117,0,0,0,0,0,0,0,0,257,0, +1003,0,0,0,1,448,0,516,0,0,960,0,125,4,0,1268,30,748,0,0,852,0,0,0,6,0,0,848, +236,1385,862,1811,0,0,0,0,698,803,0,0,0,0,0,0,0,610,992,0,0,878,0,1847,0,0,0,0, +0,0,0,383,0,1404,0,0,0,0,986,0,347,0,0,0,0,0,0,0,0,0,0,0,592,572,0,1411,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,606,0,0,0,0,0,0, +0,0,0,0,0,0,0,1829,0,0,0,0,0,0,0,0,0,0,0,0,700,748,0,0,0,0,0,0,365,0,0,127,0,0, +83,198,0,0,0,0,0,0,864,55,0,0,0,0,726,1752,0,0,0,0,0,0,0,0,0,0,0,0,0,1066,0,764, +0,0,0,0,683,0,550,309,0,0,874,1212,0,0,0,1364,0,986,381,723,0,0,0,1573,0,0,0,0, +0,1025,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1559,0,0,0,0,493,133,0,0,0,0,148, +119,0,0,0,0,0,0,537,14,541,0,635,126,0,0,0,495,0,0,0,0,861,998,1009,0,0,0,0,0,0, +0,359,368,0,0,0,0,304,1577,0,0,0,0,0,1107,0,0,0,0,0,929,0,0,0,1142,0,0,0,0,289, +175,0,432,0,219,0,0,0,0,0,785,0,0,595,0,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0,0,0,0, +931,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1323,0,0,0,0,290,0,559,1751,127,0,0,0, +934,1167,0,963,0,260,0,0,0,573,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +580,1689,0,0,0,0,0,0,0,0,0,1164,0,0,982,1922,0,63,0,0,0,0,0,793,0,0,0,0,0,0,0,0, +0,0,0,0,0,67,790,0,0,0,0,0,0,0,0,0,0,391,443,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,271,0,0,0,0,0,0,0,0,0,0,0,1140,0,0,0,0,340,300,0,897,0,0,0,0,0,0, +0,0,0,0,890,0,0,0,0,818,321,53,0,0,0,0,0,0,0,0,0,468,0,243,0,870,0,0,0,1765,121, +0,0,0,180,518,0,822,419,634,0,0,0,0,0,0,0,0,0,898,0,0,0,0,454,36,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,806,0,0,0,0,0,0,0,0,0,0,0,0,1326,0,104,0,0,0,0,0,0,0, +0,0,260,0,0,0,0,0,0,0,0,0,0,0,0,542,45,0,0,263,1516,42,0,0,0,0,0,468,0,1005,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,288,87,0,0,0,0,0,0,0,0,502,988,133,0,0,0,0,0,0, +141,0,0,872,1842,0,0,0,0,0,0,0,0,261,619,0,0,0,0,189,246,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,678,0,0,0,0,0,0,0,0,0,0,0,0,285,35,0,517,0,0,0,0,0,0,0,0,0,0, +540,214,667,0,74,0,0,125,0,0,0,0,0,761,131,0,0,0,0,0,0,0,0,0,0,0,0,0,333,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1338,94,0,0,0,0,0,0,0,0,0,0,0,0,449,0,646,103, +86,641,2028,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,869,87,277,117,39,0,0,0,0,0,0,0,0,938, +297,0,0,0,0,558,464,0,0,0,0,0,0,0,0,0,0,731,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1608,0, +0,0,0,0,0,0,1429,0,0,733,1010,0,0,338,1656,0,0,0,1038,979,2010,0,0,0,0,0,0,0, +1005,0,0,121,0,0,0,219,20,0,0,0,0,0,0,872,1440,0,0,0,683,0,1070,0,0,522,0,0,0,0, +439,669,0,0,0,0,0,0,0,0,1245,0,0,0,0,0,1218,0,0,547,233,0,0,0,0,0,0,0,0,0,482,0, +0,0,0,0,0,0,886,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,795,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,371,0,0,0,0,0,0,0,0,0,0,0,0,0,622,0,625,0,0,0,339,29,0,0,338,0,0,0, +0,130,0,0,0,0,0,0,0,0,0,307,0,0,0,0,0,0,0,0,0,0,2044,0,0,0,0,0,0,0,0,308,770,0, +0,0,0,0,1266,0,0,0,0,0,0,0,0,0,400,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,690,739,0,0, +0,0,0,0,0,990,0,0,0,1831,0,0,0,0,0,0,0,0,0,0,0,0,0,613,0,0,0,0,0,0,0,0,0,0,0,0, +0,763,0,878,0,0,0,977,0,100,0,0,0,0,0,0,0,0,0,463,0,0,0,0,623,318,0,0,296,463, +137,0,0,454,0,0,0,1527,58,0,0,0,0,0,0,0,18,48,0,0,0,0,0,729,0,0,0,442,0,0,0,0, +40,449,0,853,0,0,0,0,0,0,227,0,0,0,0,0,0,1491,0,0,0,0,0,0,0,0,0,0,161,55,0,450, +0,1174,62,0,207,0,0,0,0,0,0,0,0,869,0,0,0,0,80,213,0,0,0,0,0,0,0,0,0,0,354,820, +0,0,747,0,0,0,954,0,0,1073,0,556,0,0,0,692,0,191,0,804,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,831,162,0,0,35,0,0,0,0,0,0,0,0,1235,0,0,0,0,0,1234,0,0, +0,0,0,0,0,0,0,0,96,0,0,0,0,0,0,0,149,0,0,0,902,204,0,0,833,0,287,366,0,0,0,0,0, +0,992,2020,0,0,0,0,0,0,0,0,0,0,0,356,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,784,0,0,567, +630,0,0,0,539,0,0,27,0,0,0,0,0,0,0,0,0,0,755,0,0,0,0,0,0,0,0,0,0,0,0,814,0,0,0, +0,0,0,0,0,0,0,0,0,0,987,0,0,255,761,194,0,1086,0,0,0,0,0,0,1016,0,0,1396,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,562,271,913,0,0,0,0,0,0,0,0,320,153,45,475,0,0, +0,0,0,0,0,713,0,327,0,0,0,0,0,0,604,552,3,359,0,0,0,0,853,80,0,0,0,0,0,0,0,2016, +6,887,0,0,0,0,975,0,961,0,0,0,0,0,916,1891,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,100,101,390,708,0,0,0,587,983,512,0,0,0,0,0,0,0,0,0,0,0,645,0,0,0,851,0,0,0, +0,0,498,140,217,0,0,0,1448,0,0,0,0,0,0,0,0,0,905,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +643,105,0,792,0,0,0,0,0,0,0,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,0,535,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1748,0,0,0,0,0,754,0,0,0,0,0,0,0,0,0,0,0,0,91,0,0,1565,0,91,792, +939,3,370,0,0,0,0,95,0,0,0,0,551,7,619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1150,0, +0,0,0,0,0,0,0,0,0,0,0,0,671,0,0,0,0,0,888,368,149,0,0,105,1134,0,983,0,0,458,31, +0,643,0,0,0,312,0,740,0,0,0,1642,0,0,0,0,0,0,0,236,0,0,0,0,0,0,0,59,68,0,0,0,0, +0,867,795,0,0,0,0,970,1977,0,0,0,0,0,0,0,1148,0,775,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,970,0,0,0,0,0,0,0,0,0,665,71,0,0,0,0,827,0,0,0,0,0,0,0,0,0, +0,479,0,0,0,0,0,0,0,0,99,607,0,0,0,0,0,0,0,1960,0,0,0,793,0,0,871,41,0,0,241,94, +0,0,0,0,209,0,0,1497,0,0,0,0,0,0,0,0,0,98,0,0,0,463,0,0,0,0,291,0,0,0,0,0,0,0,0, +0,0,984,0,0,0,0,0,205,0,0,0,0,0,0,205,42,0,801,0,0,0,0,0,635,0,0,533,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,371,0,1282,0,0,0,825,0,0,0,0,0,0,0,0,0,357,879,467,0,317,0,0, +0,0,0,0,0,924,0,0,0,0,849,1795,0,0,0,0,895,1799,43,0,0,0,0,0,0,0,0,0,0,1820,0,0, +0,0,0,0,0,525,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,0,493,0,174,417,0,0, +0,0,0,583,733,0,0,0,0,0,0,481,215,0,0,0,0,477,0,0,0,0,0,0,0,0,308,0,0,0,0,0,0,0, +0,297,126,0,0,361,1551,0,0,0,0,0,0,871,1807,0,0,0,0,0,1307,0,685,0,0,0,0,0,0,0, +797,0,858,0,565,0,0,0,0,0,0,0,0,0,0,0,0,434,252,826,0,0,0,0,0,0,791,0,0,0,0,509, +231,178,601,0,0,0,0,0,0,0,0,43,1591,0,0,0,0,0,1683,0,0,0,0,45,0,0,0,0,0,0,0,0,0, +0,1120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,556,494,0,398,0,0,0,1030,0,0,0,0,0,0, +168,0,0,0,0,0,0,0,0,0,0,973,0,642,0,0,0,0,0,0,0,0,0,1615,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,378,594,0,1093,0,679,112,0,0,0,0,1492,540,1374,714, +1486,0,0,0,0,825,1511,0,0,0,0,0,0,0,0,0,0,0,0,0,952,0,0,736,143,0,700,0,1540,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1557,0,0,0,860,990,0,0,0,807,0,0,0,0,0,131, +515,0,646,0,0,0,0,117,728,508,121,0,0,0,0,0,0,357,0,0,0,0,0,0,237,0,0,0,0,0,0,0, +0,0,1784,0,0,0,0,0,0,0,0,0,0,0,713,348,1536,0,738,0,0,0,0,0,0,0,434,0,0,0,0,0,0, +366,1877,39,0,0,0,0,0,0,580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,873,0,0,0,0,171,0,625, +550,107,343,943,0,0,0,0,0,0,0,768,0,0,0,0,0,0,0,799,0,0,0,894,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1673,0,0,0,0,0,0,0,0,0,0,0,1052,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +272,0,441,0,0,3,9,0,0,0,1182,0,1346,0,0,0,0,0,0,0,0,682,0,0,1004,24,0,0,968,0,0, +0,2,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,185,0,0,0,578, +474,0,0,0,0,0,0,0,0,0,0,0,0,0,0,113,530,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,556,0,0,0,0,0,0,16,1317,0,0,97,0,0,0,703,0,0,0,0,0,0,0,0,892,0,0,0,1571,0,0, +426,186,0,1101,0,0,0,0,0,0,0,0,937,585,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,644,291, +0,0,0,0,749,0,162,0,0,381,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,762,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,628,21,0,0,0,0,0,0,0,0,919,0,0,0,0,0,0,0,0,0, +633,0,0,0,0,332,0,0,0,0,0,0,0,0,0,1489,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,832,398,0,645,0,0,0,13,0,0,0,0,0,0,0,0,0,0,20,0,800,0,0,0,0,0,0,0,0,0, +0,0,0,0,1993,0,0,0,0,769,0,0,0,665,0,0,0,0,0,0,0,0,0,0,1426,0,0,0,0,60,0,0,0, +641,1874,0,644,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1757,0,0,0,0,0,937,0,1652,0,654,0, +0,0,0,0,0,0,527,0,0,0,0,0,0,0,0,0,0,0,0,0,226,0,0,0,0,0,1486,0,0,0,0,0,0,0,0,0, +0,0,325,0,0,0,0,0,0,0,1345,0,0,91,0,404,0,0,0,0,0,0,0,0,0,0,0,0,973,0,0,0,0,0,0, +0,1176,0,549,0,0,0,0,0,0,0,0,0,0,976,0,0,0,0,0,21,0,0,0,0,0,51,0,0,0,0,314,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,198,6,0,1093,0,0,0,0,0,0,0,0,0, +0,0,0,0,1776,0,0,0,0,0,1528,0,419,0,0,0,0,0,0,0,0,76,138,0,0,0,0,638,29,0,0,0,0, +0,0,0,1418,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,1710,0,0,0,0,0, +0,0,0,0,0,0,0,532,23,0,0,0,0,0,0,0,862,0,0,946,592,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,70,0,0,0,0,0,0,0,0,0,812,0,0,0,76,0,0,988,0,442,0,0,0,896,0,0,0,0,0,0, +483,0,0,0,0,1709,0,0,0,0,0,0,119,0,0,0,117,0,309,0,0,0,0,0,596,976,0,0,0,0,0,0, +0,0,0,0,0,768,0,0,0,0,0,0,0,0,0,518,0,0,0,0,0,0,0,0,0,0,0,0,0,0,863,0,0,0,24, +145,1020,0,0,1984,0,0,0,0,0,0,0,658,0,0,0,0,0,0,0,0,0,0,106,1827,0,1010,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,582,87,0,0,0,0,0,0,0,267,0,0,0,703,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,496,0,0,0,0,1121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,249,561,0,0,0,0,0, +0,0,760,0,0,154,0,0,0,255,0,419,323,0,0,0,0,0,368,0,0,0,0,0,0,0,0,0,0,522,0,0,0, +0,0,0,0,551,562,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,92,0,0,0,0, +0,0,0,284,525,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,958,0,0,594,0,0,0,0,0,0,6,479,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,61,0,0,0,0,0,0,0,820,1641,0,1556,0,0,0,0,0,0,0,302,0,0, +0,0,0,148,0,0,676,0,0,0,0,0,0,1674,0,0,0,0,0,0,178,0,0,0,0,0,0,0,94,389,0,0,0,0, +91,8,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,747,0,0,0,0,0,0,0,1746,0,0,0,0, +0,24,0,1352,158,1530,0,0,718,130,280,1401,0,0,0,0,0,1946,8,0,0,0,0,1607,0,0,0,0, +0,0,882,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,417,0,0,0,1597,633,433,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,234,0,0,0,0,0,0,0,0,680,1950,0,0,0,0,249,5,0,0,0, +0,0,0,0,0,0,1216,0,1773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,509,180,0,0,0,0,0,0,0,1002, +0,0,0,0,0,0,0,0,0,0,0,0,0,931,0,0,0,0,0,0,0,0,747,943,0,1837,0,0,0,0,0,0,0,641, +0,0,0,0,280,0,0,0,5,0,0,0,0,0,72,545,0,0,0,0,0,0,0,0,0,742,0,0,254,151,872,0,0, +0,0,0,0,0,0,0,0,0,0,921,0,0,517,833,0,1680,0,0,436,251,584,0,0,0,0,0,0,0,0,0,0, +0,24,500,0,0,0,0,0,0,0,0,195,1775,514,389,0,0,0,0,0,0,0,743,0,0,0,0,0,0,292,0,0, +0,227,1283,774,1805,0,0,0,0,0,0,0,0,0,0,119,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,913, +1910,0,0,0,1826,490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1162,700,30, +0,0,0,721,839,0,0,0,617,0,0,0,0,0,0,0,0,0,169,428,0,0,0,0,0,1648,637,1205,0,0,0, +1596,0,0,4,266,0,0,0,0,0,0,0,0,0,0,0,862,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0, +0,279,157,391,604,0,0,713,945,877,973,0,0,0,0,0,0,0,0,0,0,0,0,0,0,859,567,628, +1846,0,0,0,0,0,0,0,0,0,762,0,0,191,0,0,0,0,298,0,0,767,909,0,0,0,0,0,0,0,795,0, +0,301,0,0,1970,0,0,0,0,0,0,0,0,0,1236,0,0,0,0,0,0,644,369,15,0,160,71,0,0,0,0,0, +1447,0,0,0,0,0,0,0,0,735,1255,76,0,0,0,0,0,0,0,0,0,0,474,0,0,0,0,0,0,0,0,0,0, +841,0,0,0,0,0,0,0,0,0,0,836,0,0,0,0,0,1622,0,0,735,0,0,0,0,1601,804,1390,394,0, +0,0,0,0,0,96,0,289,0,0,35,688,0,0,0,667,0,513,0,0,0,0,0,0,0,2034,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,704,0,1524,0,1078,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,306, +0,0,0,0,0,0,0,431,0,1196,0,0,54,0,15,1448,0,1418,0,0,0,0,0,0,0,0,0,907,0,0,0,0, +0,0,194,1767,0,0,0,0,0,840,0,900,0,0,0,0,0,0,0,0,0,0,0,1436,0,0,0,0,642,1560,0, +0,0,0,0,0,94,386,0,0,0,0,0,0,0,0,0,0,830,416,0,0,20,731,0,0,0,0,0,0,0,0,697,0,0, +662,0,0,0,0,0,0,0,0,0,861,0,0,0,0,0,0,0,871,671,864,0,928,7,0,332,0,0,0,0,1055, +0,0,0,0,0,0,986,0,0,0,0,0,44,76,0,0,0,0,0,0,0,0,0,0,300,0,0,0,0,0,0,0,175,518, +831,1108,0,0,0,836,0,1852,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,843,1804,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,246,0,0,0,610,202,0,0,36,0,0,0,240,654,13,0,0,0,0,0,0,0, +0,391,0,403,0,0,0,0,0,0,0,0,0,0,75,0,366,815,0,0,631,0,0,0,0,0,0,0,0,345,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,952,0,0,0,0,0,0,0,0,0,0,0,673,35,662,0,287,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,5,34,0,0,0,0,0,0,0,0,151,0,427,0,0,382,0,0,0,329,0,0,279,0,0,0, +0,0,0,0,0,0,0,906,0,0,366,843,0,1443,0,1372,992,0,36,123,0,649,0,0,0,0,0,767,0, +1018,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,995,0,0,0,0,0,0,0,72,368,0,0,1345,0,0,0, +589,0,0,0,0,0,0,0,0,0,1988,0,0,220,541,0,0,0,686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,32,196,0,0,0,0,0,0,0,0,0,0,0,0,0,381,0,0,0,0,0,0,0,0,0,1452,0, +0,0,616,0,0,0,0,0,0,0,0,0,1229,0,0,0,0,0,0,0,0,0,0,667,120,0,0,0,0,0,0,0,1146,0, +0,0,0,0,0,0,0,0,0,0,352,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0,0,935,0,1050,0, +147,88,0,0,923,0,0,0,0,0,934,0,0,0,0,0,0,0,0,114,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,341,222,0,0,0,0,0,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0, +637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1159,0,0,0,847,0,0,0,0,0,0,683,0,867,944,0,0, +0,0,0,1809,0,0,0,0,0,0,0,0,0,0,395,170,0,0,0,0,0,0,0,0,0,0,618,535,0,1625,0,0,0, +0,0,0,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,778,0,0,0,0,0,46,0,2032,0,0,37, +1458,0,938,363,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,314,0,0,0,0,0,0,889,0,0,0,0,0,0,0, +0,0,0,0,462,0,0,0,0,525,0,0,23,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,0,0,0,0,0, +0,498,725,0,0,0,0,7,0,0,0,0,773,0,0,0,164,0,0,0,0,0,0,0,0,936,583,659,1462,0, +220,0,0,0,0,803,0,0,544,119,0,0,0,0,0,0,0,0,0,0,0,181,176,0,1192,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,1878,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,0,0,0,0,0, +944,0,0,0,0,0,0,0,273,0,0,0,0,0,855,0,0,0,0,5,127,0,0,0,0,0,0,0,0,752,230,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,162,0,654,48,156,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,240,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,197, +0,0,0,0,0,0,0,963,0,0,0,0,0,0,0,0,0,0,858,0,0,0,0,0,0,0,0,0,0,676,1978,0,0,102, +972,0,0,0,0,0,0,0,361,0,461,0,0,0,472,0,0,0,0,0,0,0,0,0,0,0,0,0,0,747,905,0,0,0, +155,0,0,0,0,0,0,0,0,0,0,319,163,0,0,0,0,0,0,0,0,0,848,0,0,36,631,0,0,0,0,0,1769, +0,0,0,0,0,144,0,0,0,0,0,0,0,0,0,0,369,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,555,247,0,0, +996,0,0,189,0,0,0,0,0,0,0,0,0,0,280,0,0,0,0,0,0,0,0,0,0,0,526,746,0,0,345,0,0,0, +1017,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,651,428,0,0,0,1162,230,327,546,792,0,0,0, +1203,0,0,0,0,0,0,0,0,0,672,189,0,0,0,0,0,0,99,0,0,0,298,0,0,0,0,0,0,555,397,0,0, +0,0,0,1157,0,0,0,0,0,0,0,0,0,0,398,1523,0,366,0,0,787,0,0,0,282,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,157,0,941,0,0,0,0,0,1336,0,0,116,0,0,0,0,0,0,787,0,0,0,0,0,0,0,0,0, +0,170,160,0,1815,0,0,0,0,0,866,0,0,0,0,0,0,0,0,0,689,0,0,0,0,820,0,498,108,0,0, +0,1119,0,0,0,244,609,1005,0,581,0,0,0,0,0,895,0,0,0,1898,0,0,0,0,0,926,0,0,0,0, +0,0,0,0,0,0,0,0,0,538,496,294,301,0,0,0,18,0,0,757,0,0,0,0,0,1263,0,820,0,722,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2028,0,0,0,0,124,1875,0,0,0,881,0,0,0,1348, +0,0,0,0,0,0,0,911,0,954,0,0,0,0,414,0,0,0,0,517,0,0,0,0,0,816,0,0,0,0,0,0,0,0, +713,0,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,593,150,0,0,0,0, +0,553,0,0,0,0,0,0,0,0,0,0,108,0,0,0,0,420,0,0,0,0,0,0,0,0,0,0,0,1777,0,0,55,493, +0,0,81,0,321,980,0,0,0,0,0,0,0,0,0,0,0,0,0,0,362,112,0,74,0,0,0,0,0,0,0,625,0,0, +0,0,0,0,377,16,0,0,61,281,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,1031,0,0,0,0,0,0,51,0, +0,0,0,0,0,0,211,309,15,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,789,173,0,439,9,648, +0,0,294,0,0,0,0,0,0,0,374,8,0,1099,0,0,0,0,0,0,0,575,0,0,0,518,0,0,0,702,0,0,0, +0,0,0,87,0,0,0,438,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,464,122,0,0,0,1802,0,0,0,0, +0,0,499,0,0,0,87,476,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,840,283,0,0,0,0,1620,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,609,1160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,600, +323,372,0,0,0,0,471,722,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0, +477,1304,0,1774,0,0,88,0,438,12,0,0,0,0,0,0,0,0,671,997,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,639,22,0,0,782,681,0,0,0,0,0,0,0,0,0,0,1013,664,0,942,0,1349,0,0,0,0,0,0,0, +0,0,0,0,0,356,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,215,289,0,1975, +109,450,0,0,0,0,0,0,0,0,0,0,705,0,0,664,0,0,0,0,0,0,0,1238,0,0,318,0,0,0,0,0,0, +0,0,0,0,0,0,0,960,1872,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,0,0,0,0,0,0,0,0,0,239, +777,0,26,0,0,0,0,0,0,0,0,0,0,0,0,375,414,0,17,0,0,0,1350,0,955,0,0,0,0,0,0,0,0, +887,960,0,0,0,0,0,0,0,0,0,0,708,710,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,919,0,0,0, +0,502,280,7,45,0,0,0,0,777,0,0,0,0,410,0,1110,0,0,0,0,0,0,414,341,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,787,0,0,0,436,0,0,0,0,0,0,0,1707,613,377,96,0,0,0,0,451, +0,0,0,0,0,0,0,0,0,0,0,0,0,680,0,483,916,0,0,0,0,0,0,937,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,739,0,0,0,0,0,0,0,0,82,0,0,663,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,128,0,0,0,0,0,0,0,0,1087,0,0,0,0,0,0,0,503,0,0,0,0,0,0,9,113,104,324,0,460,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,935,702,434,485,1014,949,423,0,900, +0,0,0,0,0,0,0,2018,574,0,0,0,0,0,0,0,0,0,0,0,0,1206,0,0,0,0,0,0,0,0,38,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1022,0,0,0,0,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2029,0,0,0,0,0,0,0,0,0,0,0,0,523,0,0,0,0,0,0,625,0,0,425,37,0,0,0,1943,0,0,0, +0,0,765,0,0,0,0,0,0,0,0,0,0,551,0,0,0,0,0,0,0,0,0,0,0,0,168,0,0,1010,0,0,1994,0, +0,0,91,0,0,0,0,532,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1884,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,240,15,0,0,0,1227,0,1534,0,0,0,0,0,0,0,0,0,0,0,0,0,0,392,0, +0,0,0,0,0,0,0,0,0,0,0,655,562,395,0,0,0,501,1019,0,0,0,0,509,267,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,1099,0,0,0,0,0,0,948,0,0,0,0,0,0,0, +462,114,0,0,258,404,0,1717,0,0,0,0,82,1061,0,724,0,0,0,0,0,1133,0,0,0,0,0,0, +1021,841,0,1021,0,0,0,0,0,0,0,0,0,0,488,373,37,0,0,0,0,564,0,0,0,0,0,513,0,0,0, +825,0,0,899,0,0,778,0,0,12,1417,0,1116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,114,545,0,5, +0,0,0,0,0,0,0,192,0,0,763,0,0,0,0,0,0,0,755,759,0,0,0,0,0,0,0,0,0,370,0,1237,0, +0,0,0,0,0,298,87,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,31,0,0, +0,0,0,0,814,991,0,757,57,0,0,0,0,0,0,0,0,0,540,0,0,0,0,608,0,0,0,0,0,0,0,0,1014, +0,0,0,902,0,0,0,0,553,1668,0,0,0,0,0,0,0,0,0,559,60,0,0,0,0,0,511,0,0,675,0,0, +156,0,0,0,0,0,0,709,0,698,0,0,0,1745,0,0,0,0,0,0,0,0,0,714,0,0,0,0,0,0,0,0,206, +8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,776,0,0,0,0,0,0,0,0,0,1272,0,0, +0,0,0,1059,0,0,0,0,0,0,406,0,0,0,0,0,0,0,0,0,0,947,0,0,0,0,0,0,168,0,0,0,0,0,0, +870,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,554,0,0,0,0,784,908,0,0,0,0,0,0, +0,396,358,0,0,0,0,0,0,0,0,2,228,0,0,0,0,0,0,0,0,0,0,0,845,14,0,716,1820,594,0, +81,1428,0,161,0,782,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,998,0, +0,0,0,0,0,0,0,0,0,0,0,1043,0,1496,0,0,0,0,0,0,0,0,781,0,0,0,0,0,0,0,817,1114,0, +1814,958,0,0,0,0,812,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,236,643,0,0,0,0,0,0,0,0,0,1172,0,0,0,0,0,0,0,0,0,1338,0,0,0, +0,0,0,0,0,0,0,0,54,0,0,0,256,0,0,351,0,955,1885,0,469,0,0,0,1270,0,744,0,313,0, +0,0,0,0,0,0,0,402,969,0,0,0,0,0,0,50,0,0,0,0,572,0,0,0,0,847,0,0,0,0,0,0,0,248, +43,0,369,0,0,0,0,0,0,0,0,0,0,0,0,0,766,0,363,0,0,0,0,0,0,0,0,0,0,0,678,0,0,409, +258,82,249,0,0,0,0,0,0,0,0,0,0,0,0,32,393,0,788,0,0,0,1281,509,1968,0,0,0,0,39, +291,0,0,0,589,0,0,54,1059,0,0,0,0,0,0,824,0,0,0,0,0,0,0,0,0,0,1005,0,1598,0,0,0, +0,0,919,0,0,0,0,0,0,0,0,52,132,0,0,0,0,0,328,0,0,0,0,173,0,0,0,0,0,65,1411,0,0, +0,0,0,0,0,0,0,0,442,0,842,0,0,0,0,0,0,0,0,0,534,0,0,0,0,0,0,0,0,0,0,0,0,0,845, +210,0,0,0,0,0,0,0,0,892,0,0,223,0,0,0,0,529,0,0,0,807,0,137,218,0,1444,0,0,0,0, +0,332,661,0,0,0,0,0,0,0,76,1517,0,0,0,0,0,0,0,0,0,0,0,418,0,0,0,0,0,0,0,0,481, +379,0,0,0,0,0,149,18,0,0,0,0,0,0,0,0,742,304,142,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,799,925,195,51,0,0,0,0,688,0,0,0,0,697,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1169,751,0,0,0,452,929,0,221,0,1437,0,0,0,0,955,1251,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,132,0,0,0,0,0,865,0,0,0,0,0,0,0,767, +672,42,0,0,0,1050,0,0,0,0,0,0,0,0,368,44,0,0,0,0,0,0,0,570,29,0,0,0,0,0,0,227,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,522,0,0,0,0,0,0,0,1529,0,0,0,0,0,0,739,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1667,0,0,0,0,0,0,132,511,0,138,208,1020,0,0,23,565,0,344,0,0,0, +0,0,922,0,0,0,0,0,0,0,240,0,0,415,171,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,402,0,0,754,31,716,0,982,731,0,0,0,0,0,0,0,888,0,0,0,803,847,0,0,823, +0,0,0,0,0,0,785,0,0,2,0,0,0,0,0,0,0,532,0,0,681,0,0,314,0,384,684,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,649,447,0,1818,1007,0,321,0,66,360,0,0,0,385,0,0,0,0,0,0, +0,900,73,254,0,0,0,0,683,1959,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,86,0,0,725,0,0,0,0,0,196,0,0,0,0,0,831,0,0,0,0,723,0,0,0,0,0,994,627,0,0, +0,0,0,0,0,0,0,0,764,66,0,0,0,0,205,36,0,0,0,0,0,0,0,950,0,0,0,887,111,0,0,831, +388,165,0,0,0,0,0,155,0,0,0,0,0,0,0,0,0,0,0,0,0,0,780,755,0,0,0,0,898,146,0,0,0, +0,0,0,0,45,7,0,0,0,0,0,0,0,0,607,0,0,0,0,0,0,65,0,0,0,0,0,0,0,0,0,88,0,0,0,0,0, +621,600,0,367,0,0,0,0,0,0,0,561,0,559,0,585,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +287,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,672,157,0,0,0,0,714,0,0,0, +0,0,456,0,925,0,0,0,0,0,0,0,0,19,0,0,0,0,1473,0,0,0,0,0,0,0,0,0,0,113,0,0,0,0,0, +0,0,0,0,0,0,0,0,69,463,0,0,82,193,2,471,0,0,0,0,633,0,0,0,0,0,0,1148,129,1392, +542,803,0,0,0,0,0,0,0,0,0,0,0,0,438,0,0,0,0,0,0,875,0,0,0,0,0,237,0,0,0,0,0,0,0, +65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,563,0,0,0,9,444,0,0,43,1260,0,0,0,0,0,0, +971,0,0,699,0,0,0,0,0,1116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,829,242,0, +0,593,0,0,0,0,0,0,0,0,201,36,224,0,0,0,0,0,0,1430,0,1806,0,523,0,0,212,1889,0,0, +0,827,0,0,0,0,0,2043,136,242,0,0,0,0,0,0,284,148,10,0,0,0,0,0,0,1249,0,0,0,807, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,94,0,0,0,494,0,0,0,0,0,0,0,0,1510,0,0,0,0,0, +0,0,0,0,0,505,1306,0,0,764,268,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,384,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1703,0,0,0,0,159,964,583,0,0,0, +0,0,0,515,0,0,854,0,0,0,0,0,0,0,0,0,0,0,0,1123,0,0,0,0,0,0,0,136,0,0,0,0,0,1782, +0,0,44,1287,0,0,0,0,0,732,0,0,0,0,313,679,0,0,316,0,0,0,0,595,0,0,0,0,0,0,753, +147,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,137,0,0,0,0,414,0,1762,0,0,0,0,0,0,0,0, +0,0,0,599,0,0,0,0,0,0,0,0,0,1749,0,0,0,1627,0,488,0,0,0,0,0,83,0,0,0,0,676,0,0, +1639,0,0,0,0,0,0,0,0,0,278,0,0,0,0,0,0,97,0,14,1085,0,0,0,0,0,0,781,388,0,849, +59,229,0,0,0,0,0,1115,0,0,0,0,108,0,0,0,0,700,0,0,0,0,0,0,0,0,0,1414,0,0,0,0,0, +0,0,0,0,0,0,0,0,660,737,1035,0,0,0,0,0,0,521,690,0,0,0,0,0,0,0,0,0,0,0,0,272,0, +0,0,0,0,0,0,0,0,0,1744,0,0,0,0,0,0,128,733,0,0,277,0,0,0,0,0,0,0,0,0,4,0,0,0,0, +0,0,0,0,0,0,0,0,0,936,1981,40,0,0,0,0,0,0,0,0,775,0,0,0,0,0,0,0,0,0,306,0,0,0,0, +0,0,0,979,0,0,0,0,0,611,0,0,0,0,0,178,0,0,0,1969,0,0,0,0,0,0,0,664,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,390,0,0,0,1510,0,0,0,0,0,0,0,0,0,0,0,493,0,0,37,0,0,0,0,724,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,1537,0,0,168,473,0,0,0,105,0,0,0,0, +627,438,0,0,0,0,0,0,0,0,0,0,11,1256,0,0,0,1626,0,779,0,0,0,0,25,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,308,0,0,0,0,0,741,0,671,0,0,0,0,649,150,0,0,99,521,0,0,3,339,0,0,0, +543,0,0,0,0,0,0,0,0,0,1358,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,234,155, +0,0,0,0,0,0,0,1628,0,766,0,0,0,0,0,0,0,0,0,0,0,0,0,829,0,0,0,1445,0,0,0,486,0,0, +0,0,2,1635,0,0,0,0,558,0,0,0,0,0,0,0,0,0,0,1461,0,0,0,0,0,599,0,0,0,0,0,0,0,0,0, +1376,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,0,0,0,0,0,0,447,0,0,66,1432,0,0,0,0, +0,0,307,0,413,609,0,0,0,930,0,0,0,0,21,939,0,0,0,0,0,962,4,651,0,0,0,0,15,579,0, +0,0,0,0,597,0,0,0,0,0,981,0,0,0,545,0,0,0,0,0,0,0,1558,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,800,17,0,0,17,0,907,0,0,0,110,0,0,0,53,458,0,1983,0,0,0,0,0,0,0,0,0,0,443,0, +0,0,0,0,0,0,0,0,0,0,924,1844,0,1232,0,0,0,0,70,519,0,993,0,0,0,0,0,0,14,530,0, +907,0,0,0,0,0,733,0,0,0,0,0,0,0,0,55,0,188,531,56,0,0,1693,0,0,0,0,0,0,0,0,441, +0,192,928,0,0,0,0,0,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1525,0,259,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,512,185,0,464,1603,0,0,0,0,0,0,0,0,0,0,0,1113, +284,720,0,0,722,0,0,0,0,0,13,0,0,0,0,0,0,0,4,289,43,0,0,0,0,0,0,1694,0,0,0,0, +193,0,0,0,0,409,0,0,0,0,0,0,0,0,0,0,0,0,308,0,0,1863,0,0,0,0,0,0,0,0,0,790,0,0, +745,1002,0,0,0,0,0,0,0,0,0,289,68,477,13,0,0,0,0,0,0,0,0,0,0,609,0,0,0,0,0,0,0, +0,0,0,0,367,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,528,0,0,0,0,0,0,0,0,0,694,58, +548,0,0,0,0,0,0,687,0,0,0,0,1749,0,0,0,0,0,0,0,0,1004,661,0,0,0,0,0,0,445,0,0,0, +74,0,0,0,0,213,0,0,0,0,0,0,0,0,0,0,0,0,0,834,0,0,189,1672,0,0,0,0,0,0,0,1548, +192,0,0,0,0,0,0,0,0,0,0,0,0,0,32,751,0,78,0,0,0,0,0,0,544,1602,105,473,0,0,0,0, +0,0,156,1949,0,1779,0,0,0,0,0,0,0,0,0,0,0,763,0,0,0,0,0,0,0,0,29,0,0,0,0,0,0,0, +0,0,0,883,0,0,0,0,0,0,0,488,0,617,0,0,50,0,694,1518,785,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,546,0,0,0,0,0,0,0,0,0,0,22,0,0,0,0,1016,0,0,0,577,0,0,0,0,0,0, +184,935,114,720,0,0,100,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,95,14,0,969,0,0,0,0,0,0,0, +727,0,1021,0,0,0,0,0,1190,0,0,0,0,0,0,0,0,0,0,0,0,0,153,0,0,0,0,0,0,0,0,0,798,0, +587,0,0,695,42,0,1929,141,957,0,465,7,908,0,0,450,148,0,0,0,1166,0,0,0,0,0,0,0, +0,0,0,0,0,253,0,1003,0,0,0,0,0,0,0,0,0,0,0,46,0,0,879,0,806,0,1868,0,0,0,0,0, +1846,0,0,0,730,0,0,0,0,0,0,0,965,0,0,0,0,506,0,0,0,10,0,0,0,22,0,0,0,0,0,0,0,0, +0,0,0,0,0,960,296,0,0,0,0,0,0,0,0,0,0,0,587,0,0,0,0,20,0,0,0,32,982,0,0,0,0,0,0, +0,0,0,0,941,0,0,0,0,435,0,0,0,0,0,0,71,419,0,0,0,0,0,0,688,740,94,345,0,0,679, +582,0,0,0,0,0,0,0,945,0,0,0,0,0,0,0,0,0,0,0,0,539,0,684,1993,0,0,0,659,0,583,0, +803,0,704,0,0,0,0,0,198,181,347,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,481,405,203,0,0,99,826,0,0,0,0,0,0,0,492,0,408,0,0,0,0,0,0,0,0,0,0,4,0,0, +0,0,665,349,137,0,0,0,0,612,1270,0,0,0,0,0,371,0,0,0,826,0,0,0,0,21,1535,858, +374,0,0,0,0,0,0,311,0,0,0,991,1968,0,0,0,0,494,1647,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,769,0,0,0,0,0,642,0,0,157,123,0,0,0,1435,0,0,0,0,0,0,0,0,0,0,79,0,0,0, +0,0,0,1425,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,106,393,486,1690,0,0,0,0, +0,0,0,0,0,0,0,0,756,184,0,0,0,1382,0,0,0,175,0,1493,0,1007,0,0,0,0,0,0,0,0,0,0, +0,219,0,0,0,0,515,99,0,851,0,0,0,0,0,1278,0,0,0,0,0,0,0,1000,982,0,762,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,910,1819,0,0,0,0,0,0,906,0,0,0,0,0,0,0,0,0,0,1730,0,0, +0,0,0,0,0,0,0,0,0,1185,0,0,0,0,0,0,0,0,40,0,0,0,147,0,0,0,0,0,0,0,0,0,0,0,0,0, +650,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,30,0,553,0,0,20,597,0,1614,0,0,0,0,0,327, +49,0,0,0,0,0,0,0,78,0,0,786,134,0,0,0,12,496,0,0,0,0,0,0,0,0,0,0,42,204,0,614,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,147,247,0,0,0,0,942,0,0,2023,0,0,0,0, +0,0,67,285,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1309,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,41,532,0,0,0,0,0,0,0, +1692,0,0,0,0,55,1704,0,0,0,0,988,0,0,0,223,0,0,0,0,0,0,0,57,1123,0,0,0,0,0,1764, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2015,0,0,0,1599,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,129,0,0,0,0,0,0,0,0,0,0,0,534,0,0,0,0,0,0,0,0,0,0,0, +0,0,504,621,1248,321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1397,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,441,75,0,0,0,0,0,0,0,0,0,0,841,0,0,0,0,0,693,0,650,314,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,913,0,0,0,0,0,0,0,0,0,0,0,0,0,0,880,0,475,0, +0,1016,179,602,111,329,0,0,0,1864,0,0,0,0,846,1888,0,0,780,0,0,0,82,0,0,0,0,821, +0,0,0,0,0,0,0,0,0,0,0,956,112,0,0,0,261,455,0,0,0,0,0,0,337,385,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,184,1865,0,0,721,16,0,486,0,0,0,265,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,621,0,0,0,0,0,0,0,0,234,0,0,815,0,0,743, +1987,205,197,0,0,0,0,0,0,0,0,0,314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,219,452,589,0, +176,333,0,0,0,0,0,0,0,1110,47,0,0,0,0,0,0,0,0,0,0,0,864,0,0,300,0,1237,0,0,0,0, +0,0,0,0,0,0,0,1685,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,135,395,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,631,0,0,0,0,0,0,835,0,0,0,606,459,0,979,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,612,0,0,0,0,0,0,0,0,158,372,0,854,0,0,0,0,0, +0,0,1492,0,0,0,833,0,0,0,0,0,0,0,1739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +195,0,0,0,0,0,0,0,0,730,1997,0,0,0,0,0,0,0,0,61,0,0,0,0,0,0,0,266,751,0,0,0,0,0, +0,0,821,0,0,0,715,0,0,0,868,0,959,0,0,0,0,0,0,0,0,0,0,0,1053,0,0,0,950,0,1081,0, +1595,0,0,0,0,59,0,0,0,0,0,0,0,0,0,0,47,684,0,0,0,0,0,0,1606,0,777,0,1020,0,0,0, +1094,0,0,0,0,0,0,0,350,0,0,0,0,0,0,242,1812,0,0,0,967,0,0,0,473,286,0,0,0,0,0,0, +798,629,222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,513,337,306,0,0,0,0,0,0,0,0,0, +146,0,0,1646,0,0,0,0,0,465,0,0,0,525,0,0,0,0,0,0,299,165,0,0,0,0,0,0,0,1064,0,0, +0,0,0,596,0,0,0,0,0,0,0,0,0,0,0,0,0,0,238,1741,0,1233,451,1824,0,0,0,0,733,495, +0,0,0,0,0,1204,0,0,0,559,341,0,224,21,0,0,0,0,0,0,0,0,97,1446,0,0,0,0,0,0,0,729, +0,0,565,727,0,1948,0,0,0,519,0,0,0,0,0,0,0,0,0,1193,0,0,0,0,0,0,790,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,323,2,201,0,0,59,0,0,34,0,896,961,0,1285,0,0,46,0,479,0,0, +0,0,549,0,663,0,0,0,0,0,783,65,682,0,0,0,0,0,11,0,0,0,0,0,522,0,0,0,52,0,0,0,0, +0,383,0,0,0,0,0,0,0,0,127,0,0,0,0,0,397,194,0,0,635,0,0,0,0,0,0,0,0,0,0,975,0,0, +0,0,0,0,0,0,0,0,116,0,51,0,0,858,0,1075,535,448,0,0,0,0,0,610,0,0,0,0,0,0,0,0,0, +0,191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,267,673,319,94,92,0,551,0,0,218, +1406,69,256,0,0,952,1980,0,833,0,0,0,0,0,0,0,0,0,0,0,0,39,0,0,0,0,0,0,0,81,0,0, +0,352,634,0,0,0,0,0,618,0,0,0,0,0,0,73,339,0,0,0,0,0,0,0,0,0,0,0,0,0,0,169,759, +0,0,0,0,0,0,0,0,0,0,0,0,0,1075,0,0,0,0,0,0,482,649,0,0,0,0,0,0,0,0,386,336,0,0, +0,1035,0,0,0,0,0,0,0,0,0,0,0,924,0,73,0,0,0,0,0,1971,0,0,0,0,0,0,0,0,0,1344,0, +501,0,0,0,0,0,0,0,0,46,799,0,0,0,0,0,0,0,276,0,0,0,0,0,0,0,770,0,0,0,0,0,0,0,0, +0,0,0,0,0,158,0,0,0,0,0,1432,0,0,0,0,0,0,0,0,0,0,25,0,0,2001,0,0,0,0,0,0,0,0,0, +0,0,0,0,478,0,0,0,0,0,0,91,1461,211,602,0,0,0,0,0,0,0,0,0,1068,0,0,124,567,0,0, +0,1006,0,0,0,0,0,0,0,0,0,735,812,0,0,323,0,0,0,304,0,0,0,0,0,0,0,0,0,148,0,0,0, +0,0,0,0,0,0,523,0,0,144,730,0,0,981,0,0,111,0,0,132,0,0,0,0,0,0,890,0,0,0,0,0, +444,0,1787,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,2041,932,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,937,0,995,0,0,255,0,0,138,863,965,0,0,631,0,0,0,0,1394,16,652,0,0,0,0,0,0, +0,0,0,0,0,0,0,897,0,321,0,0,0,0,0,922,0,619,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,844,0,0,0,0,0,0,1659,0,1100,0,0,0,1173,0,1930,268,251,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,390,711,0,0,0,0,0,0,0,0,0,0,0,0,0,744,0,0,0,0,0,0,0,0,0,624,0,0,0, +1998,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1125,0,0,0,594,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,268,0,0,0,0,0,0,0,563,0,0,0,0,0,0,0,0,2,39,0,0,0,1332,0,0,0,0,0, +0,0,508,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,796,0,0,0,0,527,0,0,0,0,98,0,0,576,0, +0,0,0,0,122,0,276,37,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,645,0,0,0,0, +0,0,0,0,0,0,0,290,0,0,762,1292,0,0,0,1315,0,1955,0,0,0,0,0,0,0,0,0,0,210,131,0, +0,0,0,797,0,38,0,11,488,0,936,0,441,0,0,0,0,0,595,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +991,0,0,0,0,0,0,0,0,0,0,0,653,0,523,0,0,0,903,0,0,0,0,0,0,0,0,0,0,0,0,80,0,0,0, +0,0,0,0,0,0,432,0,0,314,0,0,0,0,232,1368,534,0,0,0,0,0,27,0,0,0,12,0,0,0,0,0,0, +0,0,0,264,736,0,1657,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1117,0,127,0,0,0,1208,0,1294, +0,0,0,0,364,0,0,0,0,0,125,1334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,792,0,0,0,0,0,0,0, +849,699,0,0,0,0,0,968,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,1446, +124,397,0,0,0,0,0,0,0,0,0,0,0,641,0,0,0,0,0,0,0,0,0,0,0,0,127,346,0,0,517,75,0, +0,0,0,0,0,0,0,83,0,0,0,0,0,0,1031,0,0,0,0,0,0,0,1470,0,954,0,0,345,304,410,0,0, +0,0,734,0,0,0,0,0,1822,0,0,0,1798,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,161, +1865,69,0,0,0,0,0,0,922,0,0,0,0,0,0,0,0,0,0,0,541,0,627,0,0,0,0,0,0,0,0,0,166,0, +0,0,0,0,0,0,0,0,849,0,0,0,0,0,0,0,717,0,0,0,0,0,0,0,0,0,0,0,0,0,0,600,0,0,0,0,0, +0,654,0,0,188,273,0,0,0,543,0,410,87,0,0,941,0,0,186,250,0,1785,0,0,0,0,0,1339, +462,961,0,780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,529,0,0,0,0,0,0,474,1276,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,24,948,0,0,0,0,657,753,0,0,0,0,941,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,706,985,837,0,1861,0,0,0,0,0,0,0,0,0,0,0,0,0,0,292,933,0,0,0,0,0, +0,0,0,0,767,0,0,0,0,0,0,0,641,0,0,0,1233,114,0,883,0,274,2008,0,1794,285,0,0, +571,0,0,0,0,0,0,0,0,0,0,823,960,16,617,0,431,0,0,0,0,0,0,0,0,0,0,567,0,401,0,2, +781,424,33,0,2006,0,0,274,0,0,1882,0,794,0,0,0,1848,0,0,0,0,0,0,448,47,0,0,0, +1199,0,0,0,0,0,0,0,0,417,0,0,0,0,0,0,0,0,0,0,295,0,0,0,0,0,0,0,1019,0,0,0,0,0,0, +0,0,0,0,0,0,0,620,0,0,0,0,464,0,0,0,0,208,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,442,0,930,0,0,0,0,0,516,68,0,0,0,0,0,1128,104,0,0,0,0,0,0,0,0,787,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,491,0,0,0,0,0,0,711,0,0,9,0,101,441,0,0,0,0,0,0,0,0, +0,0,160,396,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,679,326,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,1128,0,0,0,0,0,737,0,1796,0,0,0,0,0,0,0,0,0,0,0,0,338,574,0,0, +0,0,0,1096,491,405,0,0,0,0,0,1081,0,0,0,0,0,0,0,0,0,0,0,0,0,1676,0,1207,0,0,0,0, +0,0,969,354,0,0,0,0,598,0,297,0,0,0,0,0,0,0,0,1772,751,0,37,0,0,1828,0,0,0,0,0, +0,0,0,0,257,191,582,0,0,0,0,0,0,790,0,0,0,0,0,47,0,0,0,0,0,0,0,449,306,1011,0,0, +0,0,0,299,0,0,0,0,0,0,837,0,0,0,0,0,0,10,329,0,0,0,0,0,1320,0,0,0,0,0,0,158,657, +0,1191,0,0,0,0,0,0,7,0,974,1939,0,1665,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,288, +66,0,0,0,0,494,175,0,1643,0,0,0,0,0,0,0,0,570,750,719,0,0,0,0,0,0,0,0,0,0,0,0,0, +13,0,0,1247,0,0,221,356,0,0,0,0,0,0,0,0,0,0,694,1809,0,0,0,0,0,0,0,411,0,44,31, +0,0,0,0,669,0,673,0,0,0,0,0,0,0,0,0,1303,704,299,0,0,0,275,0,0,216,1761,0,0,0,0, +0,0,0,0,0,0,0,1319,0,0,428,0,0,0,0,0,0,0,0,0,0,514,0,0,0,0,0,0,49,55,102,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,364,0,0,0,0,379,0,921,971,52,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1258,0,0,0,1058,0,0,0,0,0,656,0,0,0,0,0,144,0,0,0,0,0,0,0,0,0,0, +0,1373,10,605,0,0,0,0,0,0,0,838,0,1012,0,0,0,0,0,0,0,0,0,0,0,0,0,0,154,365,0,0, +0,0,0,0,0,0,0,340,0,0,0,0,0,810,0,0,0,0,0,0,495,0,0,0,0,0,0,0,0,0,261,0,535,248, +0,358,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,567,445,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,697,0,0,0,1336,0,0,0,0,0,0,0,0,917,174,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,972,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,351,0,0,0,0,0,0,0,0,0,0, +0,0,0,286,0,0,56,438,0,0,0,0,0,1950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,738,0,0,0,0,0, +0,0,0,0,0,969,2047,0,0,0,0,0,0,0,818,0,0,0,0,0,0,0,866,0,0,0,0,0,0,0,1467,0,0,0, +0,0,0,0,0,0,0,0,0,0,972,0,355,0,0,0,116,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,267,189,104,0,0,0,0,1613,0,0,0,0,0,0,0,116,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,886,0,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,45,0,0,863,0,0,0,0,0, +0,0,1953,450,1773,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,381,0,0,0,0,0,0,0, +0,0,0,0,0,1142,0,1189,0,0,0,663,0,0,0,0,0,0,0,846,0,0,528,0,393,378,0,0,0,0,0,0, +325,899,680,1880,0,1770,0,0,0,0,0,648,0,0,0,0,0,0,185,167,0,2046,0,0,0,0,0,0, +249,1645,0,152,0,0,0,1733,0,0,0,0,0,1006,0,0,0,0,0,420,0,0,0,832,0,0,0,0,0,351, +0,0,0,0,6,40,0,0,60,0,0,0,0,1354,745,724,0,0,0,0,0,0,0,0,772,1951,275,108,639,0, +0,0,0,0,0,0,0,0,500,1758,0,0,0,0,0,0,0,0,0,0,0,1886,711,205,0,0,965,865,0,0,0, +534,0,0,0,0,691,0,0,0,237,443,0,878,0,0,0,0,0,1410,0,0,0,0,0,0,0,0,0,0,0,0,0, +995,0,0,0,0,0,0,0,0,0,0,0,0,0,578,0,0,0,0,881,0,0,0,0,0,0,0,0,822,0,923,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,924,0,0,0,665,0,0,0,0,0,1901,0,0,0,0,0,950,498,93, +0,0,0,1451,0,0,0,0,0,747,828,788,400,184,0,198,0,0,0,0,0,0,0,0,0,0,0,994,0,0,0, +0,0,0,0,0,615,320,0,0,0,978,843,905,0,0,0,0,0,0,0,0,850,974,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,509,0,0,0,0,0,273,0,0,0,0,0,0,0,0,0,0,0,0,0, +201,0,0,0,1041,0,0,0,1040,0,0,0,0,0,0,0,0,0,693,234,774,0,336,0,1399,22,0,805, +802,777,167,789,0,0,1705,0,0,0,0,0,0,0,0,0,0,0,10,13,11,0,0,204,264,0,0,56,0,0, +1917,0,470,0,0,0,0,0,0,0,0,0,0,0,1198,0,0,0,0,0,0,0,0,0,0,1015,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,715,0,0,1002,0,0,0,298,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,867,0,0,724,0,0,0,0,0,0,0,0,0,0,0,0,768,0,0,0,0,0,1066,0,0,0,0,67,0,174,948, +0,0,0,0,0,0,0,0,0,0,0,0,0,764,0,0,0,0,75,137,0,756,0,0,0,0,0,0,1008,842,643,0,0, +0,67,0,0,0,0,0,0,0,0,0,0,0,135,821,0,0,0,0,0,0,0,0,736,0,389,355,0,0,786,0,0,0, +0,0,0,2044,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1030,0,0,0,1083,0,0,0,0,0, +1226,0,0,0,0,356,319,8,389,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,474,0,0,0,427, +0,413,0,730,0,0,0,0,0,373,0,0,0,0,0,0,0,0,0,799,0,0,0,1793,0,0,0,322,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,89,290,2,0,0,0,0,0,0,0,0,0,0,672, +699,1860,0,0,0,737,0,0,0,1612,0,0,0,0,0,0,0,0,0,0,0,145,124,884,0,0,0,0,0,387,0, +0,0,0,0,0,0,0,0,0,0,679,0,550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1305,0,0,0,0,0,0,0, +576,0,0,0,0,0,0,0,686,0,607,0,0,37,0,0,0,0,0,0,0,0,0,101,1726,0,0,0,0,0,958,0,0, +0,903,0,0,0,0,147,0,0,0,0,0,0,0,0,0,0,0,367,0,0,0,0,690,0,705,273,0,0,887,0,0,0, +0,0,0,0,0,0,0,0,90,0,0,0,0,0,0,0,908,0,0,0,0,0,0,0,1261,0,0,497,1235,0,429,0,0, +0,0,904,0,12,125,0,0,0,841,0,0,0,0,0,860,946,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,768,0,770,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,271,0,0,0,0,0,0,0,719,0,699,581,0,0,0,0,0,0,0,0,0,0,862,304,0,631,0,0,0,0,880, +1513,0,0,0,0,0,981,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,434,0,0,0,0,0,550,0,0,476,930, +824,553,0,0,452,0,151,0,0,0,0,0,0,772,0,292,135,0,0,0,0,0,0,0,504,0,0,1089,0,0, +0,0,0,0,0,0,0,0,0,783,0,0,0,0,0,0,206,393,0,0,0,0,0,0,0,0,232,912,0,0,0,0,0,977, +0,0,716,98,0,0,0,0,0,733,0,0,0,0,0,0,0,0,19,0,0,0,0,668,0,360,0,0,0,0,0,0,656,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,726,0,0,0,0,0,0,0,0,0,0,0,0,72,0,0,1269,0,0,463,0, +0,0,0,0,0,1454,0,1287,245,0,989,0,0,0,0,0,0,0,0,0,107,164,0,0,0,0,0,0,0,1061,0, +0,0,0,2,484,0,0,0,0,0,0,0,1127,0,0,0,0,0,0,0,460,0,0,0,0,0,932,0,0,0,0,0,0,0, +588,625,0,0,0,0,76,92,0,0,0,0,0,0,0,0,0,0,0,0,0,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +763,0,622,0,0,0,253,0,546,0,0,110,0,256,916,0,0,35,212,0,0,746,0,0,0,150,0,0, +1466,0,0,0,1299,0,0,0,0,0,0,0,0,0,1518,0,0,0,0,0,0,0,0,0,0,0,0,0,1229,0,0,0,816, +0,0,0,0,0,0,159,0,0,0,0,0,734,869,126,1716,0,0,0,0,0,0,202,232,0,0,0,0,212,0,0, +0,0,0,111,1003,0,0,0,0,0,0,0,0,0,0,0,1712,0,0,216,0,0,0,0,516,0,0,0,0,0,650,0,0, +0,0,57,99,0,0,0,0,300,574,0,0,0,0,1023,0,0,302,0,1871,0,728,252,0,0,461,0,0,0, +323,0,0,0,0,0,0,775,461,0,0,0,0,0,0,172,0,0,464,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,73,727,0,1023,0,0,0,0,0,0,0,0,0,0,577,0,0,0,0,0,0,0,0,1037,0,0,0,0,0,0, +0,0,280,677,0,0,0,0,0,0,0,0,0,0,0,799,0,0,0,0,159,0,446,1730,0,0,0,0,0,0,0,0,0, +395,0,0,0,0,145,0,0,0,0,0,0,0,20,0,0,426,608,0,0,0,0,0,977,0,250,0,0,0,0,0,100, +0,0,0,0,1982,0,0,0,0,0,476,0,0,0,0,0,0,594,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,447,0,0,0,0,526,0,0,14,1124,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,188,0,0,0,0,0,0,0,0,362,301,0,0,0,1743,0,178,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,872,0,831,0,0,208,202,0,0,0,0,0,0,0,1954,0, +0,0,0,516,872,0,0,313,224,0,0,24,0,11,546,0,0,0,1937,242,241,46,0,0,0,830,1273, +0,0,0,0,0,0,0,825,327,1006,0,0,0,0,0,1580,516,366,0,0,0,0,0,1736,0,0,0,0,0,0,0, +0,0,0,0,1935,0,826,0,0,0,0,139,331,0,0,0,0,0,0,0,0,0,0,0,288,0,916,0,0,0,0,0, +1888,0,0,0,0,0,0,0,1471,0,1570,0,394,0,0,0,0,0,0,0,1931,0,1719,0,658,228,0,0,0, +0,0,374,0,0,0,0,735,0,0,0,0,0,0,323,498,0,1063,0,0,0,0,155,0,0,0,0,0,0,0,0,906, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1139,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,108,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,616, +902,0,0,0,0,0,692,0,0,0,0,0,0,823,0,0,0,305,0,0,0,0,0,0,0,681,0,0,0,0,0,214, +1004,0,0,0,0,0,0,0,23,0,0,1703,0,0,0,0,0,0,0,0,0,1443,0,0,19,714,0,0,0,0,64,737, +0,0,345,1758,0,0,579,47,0,0,539,139,0,0,0,0,388,0,0,0,0,253,0,0,0,0,0,0,252,0, +745,0,0,0,0,0,0,0,0,0,0,0,504,107,0,871,0,0,0,229,0,0,0,0,0,903,0,0,71,0,0,549, +6,47,0,0,0,0,0,0,0,0,0,980,865,705,0,0,0,161,0,0,0,0,143,1331,0,0,0,1388,33,724, +0,0,0,19,0,0,0,395,0,0,0,0,0,846,210,0,0,0,122,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,695,937,497,0,0,0,0,0,718,0,0,0,0,0,0,0,1581,0, +0,0,0,0,0,161,49,0,0,0,0,0,0,0,0,0,597,0,0,0,1094,0,0,0,811,908,0,0,0,0,0,0,0,0, +0,0,1471,0,0,0,0,0,0,0,0,0,0,42,1935,0,0,0,2014,66,2007,0,0,586,0,0,0,0,0,0,0,0, +0,28,1077,0,0,0,1221,0,0,62,0,0,0,0,0,0,0,0,0,0,1766,0,0,0,0,0,0,0,0,0,0,0,0,25, +0,499,1388,0,0,97,10,0,0,0,0,0,481,0,0,0,0,0,0,0,0,0,0,37,134,155,486,0,1442,0, +0,0,0,0,591,0,0,0,0,0,0,310,1173,0,0,0,0,409,1156,0,0,0,482,0,0,263,926,0,0,0,0, +0,0,0,0,0,0,0,0,0,804,0,0,0,0,0,0,0,0,0,0,0,0,0,1265,0,415,0,348,0,0,0,1012,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,165,1803,0,0,0,0,0,0,0,408, +0,0,0,0,0,0,257,1321,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1138,0,0,0,249,0, +0,0,576,0,0,0,0,231,0,0,0,288,0,0,0,0,0,0,0,0,0,433,1487,569,1678,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,87,0,0,0,0,0,779,538,0,0,0,413,0,0,0, +0,0,0,0,0,0,0,495,0,0,0,0,0,191,54,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,530,567, +0,0,0,0,0,1484,0,0,0,0,0,0,815,609,0,0,0,0,0,484,0,0,0,0,0,0,0,0,0,0,900,0,0,0, +0,1335,0,1724,0,0,0,0,0,0,0,0,0,0,0,640,0,0,0,0,0,0,0,0,0,0,0,1831,0,0,0,0,0,0, +0,0,0,0,0,0,0,474,0,0,0,0,0,0,0,0,0,1103,0,1504,655,1034,0,0,0,0,0,305,0,0,0,0, +0,0,0,0,0,1236,0,0,429,217,0,0,0,0,739,278,0,0,0,0,0,0,0,708,0,0,0,0,0,1840,233, +0,0,0,0,0,0,0,0,2017,0,0,0,0,0,1488,0,0,0,1590,0,0,0,0,0,1800,28,0,0,0,0,0,0,0, +0,0,45,0,36,0,22,1442,378,0,0,0,0,0,0,1507,0,0,0,0,0,0,0,0,0,0,39,0,0,1054,725, +1955,0,2036,0,0,0,0,0,0,0,0,0,0,896,1871,0,0,0,0,0,0,0,0,0,0,805,0,0,0,0,2046,0, +0,0,0,17,712,0,617,55,320,271,0,0,0,0,0,0,0,0,0,445,0,184,103,0,0,0,0,0,0,0,0, +659,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +337,0,0,0,506,0,0,0,0,0,843,77,0,458,0,0,0,0,0,1420,382,109,142,330,0,0,0,0,0,0, +0,0,0,0,0,0,87,0,0,0,492,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1239,0,0,0,0,0,0, +211,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1049,0,321,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1985,0,0,122,0,0,234,0,0,0,1098,0,0,0,0,0,0,549,253,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,522,131,0,0,149,0,0,0,0,0,0,0,0,0,0,0,0,0,0,507,0,0,0,0,811,630,0,0,0,343, +0,0,0,0,0,448,591,455,0,1381,0,0,0,0,0,0,0,575,0,0,0,0,0,1175,0,0,0,0,0,0,0,0,0, +653,0,0,0,1761,0,1198,0,0,0,0,297,1127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,678,0,0, +164,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,35,0,45,0,0,0,0,0,121,0,0,0,0,0,0, +0,0,125,0,0,0,1622,0,0,0,0,0,721,145,0,0,0,970,792,0,0,0,715,0,0,0,0,0,1999,0,0, +74,531,0,0,65,0,0,0,105,220,0,0,0,0,0,0,0,960,0,0,0,0,0,0,428,19,0,0,401,96,0,0, +0,0,0,1595,116,0,1021,0,0,0,0,0,750,1961,0,0,148,0,0,0,0,0,0,0,0,0,0,0,0,0,75,0, +0,1383,0,0,0,0,0,0,0,0,0,0,0,0,0,0,779,0,0,0,0,0,0,0,0,598,0,424,0,0,0,0,0,0,0, +1222,0,0,0,876,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,133,0,0,0,0,187,0,8,0,0,0,0,0, +0,0,429,0,685,0,0,0,0,0,0,0,0,0,0,0,132,472,0,0,0,0,0,0,0,0,0,938,0,0,874,0,0,0, +0,0,774,0,0,0,0,0,92,0,0,0,0,0,0,830,701,0,0,0,0,0,426,350,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,603,59,0,0,0,0,0,0,0,0,0,0,293,0,0,0,0,0,0,0,0,0,0,0,0,0,0,441,163,4,0, +0,0,0,0,0,0,0,0,806,0,0,0,0,0,0,233,0,0,0,0,1994,0,1739,0,0,393,0,47,1038,0,0,0, +309,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,363,0,0,0,175,0,0,0,0,0,0,0,666, +0,0,1675,0,1600,0,0,0,808,0,0,0,0,0,0,0,0,0,0,0,280,54,0,0,0,0,0,0,0,0,421,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,249,0,0,103,254,0,262,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,805,0,0,0,0,0,0,0,0,0,1630,0,0,0,0,0,0,0,0,0,0,0,0,0,671,972,989,0,0, +0,0,0,0,0,889,0,0,0,1382,0,0,0,0,0,0,0,775,0,0,0,0,0,0,0,0,0,0,388,202,0,0,0,0, +16,560,0,0,0,841,0,0,566,0,0,0,938,0,0,0,0,0,0,0,0,0,0,912,0,0,0,1361,0,0,0,0,0, +0,618,236,0,1854,0,0,318,190,0,1376,0,0,0,0,0,0,0,349,0,0,0,0,951,1972,0,0,0,0, +0,0,344,0,0,0,0,0,0,0,0,850,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,910,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,163,85,0,487,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,145,0,83,0,0,1013,0,0,0,1922,0,0,169,557,66,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1193,82,0,352,454,57,0,0,1333,396,107,0,370,0,0,0,0,0,0,0,0,0,204,0,0,0, +0,0,1706,0,0,0,0,0,0,0,0,0,0,0,0,394,1204,0,0,0,0,0,1007,0,0,0,1696,0,1519,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,981,0,0,0,0,1072,0,0,0,712,0,1629,0,0,0,0,0,0,0,728,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1271,0,0,0,1608,16,0,0,0,0,485,0,0,0,0,0,0, +153,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1991,0,0,0,0,0,0,0,0,52,0,21,0, +0,0,0,0,0,0,0,0,819,0,0,0,0,0,917,0,0,0,0,784,0,0,0,0,135,0,0,0,0,0,454,0,0,0,0, +0,0,0,0,0,852,1719,0,0,0,0,0,852,0,0,0,0,0,952,0,0,0,0,568,0,0,0,0,0,448,0,0,0, +67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1826,657,0,729,666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +669,0,0,0,0,0,0,0,402,0,0,152,0,0,0,0,912,0,0,0,0,0,0,51,320,0,445,0,0,0,0,308, +0,0,0,0,0,386,0,0,239,0,0,130,83,0,143,0,348,0,0,0,0,0,0,0,958,0,0,0,0,0,210,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,430,0,0,0,0,0,0,0,0,0,0,0,0,7,213,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,801,0,0,0,0,0,0,0,0,0,936,0,108,0,0, +0,0,0,0,0,0,0,885,587,219,398,364,0,1165,0,0,342,241,303,0,0,0,0,0,0,0,0,0,0, +1454,0,0,0,0,0,0,0,0,0,0,254,562,0,786,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1294,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,493,216,0,0,0,0,219,341,0,0,0,0,0, +0,0,0,0,0,130,1734,154,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,701,604,0,0,879,0,195, +666,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1669,0,0,0,1791,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1228,0,0,0,0,0,623,0,0,0,0,0,0,0,798,0,0,0,0,0,0,0,0,0,0,0,0,84, +122,0,0,0,837,0,0,0,0,0,0,1013,0,0,577,0,0,0,460,932,0,0,0,0,0,0,0,0,0,0,0,31, +131,0,0,0,605,0,0,0,1246,0,0,0,0,68,278,165,307,781,0,0,0,0,0,0,33,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,1113,0,0,720,1953,203,0,0,0,0,0,0,0,425,326,0,0,0,0,0, +0,0,0,0,0,241,1316,0,0,0,0,0,416,0,0,0,1300,0,847,0,0,662,358,0,0,0,0,839,1823, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,654,1522,0,0,0,0,0,0,163,0,0,0,0,0,314,978,0,0,0, +601,0,0,0,0,0,946,434,0,0,0,402,411,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,1467, +410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,483,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,677,0,0,0,0,0,0,0,0,0,0,0,0,70,0,0,0,0,1405,0,0,0,0,0,0,108,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,777,0,0,0,0,0,747,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,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,505,0,326,0,0,164,628,654,0,0,0, +37,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,668,152,0,0,0,0,0,0,0,0,0,0,0,581, +0,0,0,0,44,126,89,0,0,0,0,0,0,0,0,1531,0,0,0,0,0,0,0,0,203,1167,0,0,0,0,0,0,0,0, +531,1232,0,0,0,0,0,943,0,670,231,880,0,1617,0,0,0,1957,0,0,0,0,0,0,0,975,0,0,0, +0,0,0,0,0,0,0,0,242,0,0,0,0,0,0,0,0,0,421,0,0,14,834,0,0,0,0,0,0,0,0,0,0,0,0, +465,0,0,0,0,0,834,688,413,855,0,0,0,590,0,0,0,0,0,0,0,0,114,0,0,0,0,0,0,0,0,0,0, +0,45,169,0,0,0,0,0,0,0,0,0,0,0,198,0,0,565,585,0,0,0,0,0,0,0,0,0,0,0,0,0,691,0, +0,0,593,0,0,0,0,0,0,0,0,0,913,116,0,0,0,0,1360,0,0,0,802,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,673,308,0,709,1006,1895,0,228,0,0,0,1840,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,608,0,0,0,0,0,0,0,0,0,1573,0,2039,136,540,0,0,0,0,0,0,0, +897,0,0,938,1878,0,0,0,0,0,0,0,0,0,1469,0,999,0,299,0,0,0,0,0,0,0,578,0,0,0,0,0, +456,0,0,0,1679,163,693,0,0,0,0,0,0,48,755,0,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0, +1091,0,0,0,0,695,0,0,1464,0,0,0,0,0,975,0,0,335,0,0,1979,0,0,0,0,269,1566,630, +396,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1815,634,0,0,0,966,0,0,0,0,0,0,0,9, +412,0,958,0,0,579,382,0,212,0,0,0,0,965,681,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,655, +0,0,0,0,67,0,0,0,0,0,0,751,0,0,0,0,423,231,0,0,1016,300,0,0,0,0,100,237,0,0,0, +1370,0,0,0,1208,0,0,0,0,0,1219,129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,199,0,0,427,0,0, +0,0,949,665,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,712,0,0,0,0,0,1186,0,0,0,0,0,0,0,0,0,0,295,312,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +151,0,0,0,0,588,4,0,0,0,0,0,414,104,0,0,757,263,0,561,0,0,0,320,0,0,0,0,0,0,0,0, +0,0,0,225,0,0,0,0,37,817,0,974,0,0,0,0,0,0,0,0,0,0,0,0,0,2026,131,235,16,0,590, +1157,0,0,0,0,0,0,0,0,221,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,390,0,0,0,0, +0,0,0,1144,0,0,0,464,0,0,0,0,0,0,0,0,0,0,0,0,204,407,303,1218,0,0,0,0,5,325,0,0, +0,0,12,800,0,1783,0,0,0,0,0,0,0,0,0,0,504,621,0,0,0,0,0,0,0,0,0,920,0,376,0,0,0, +0,0,218,580,0,768,454,0,0,0,0,0,0,0,0,0,0,0,0,676,0,0,0,0,0,0,164,0,0,0,0,0,0,0, +0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,120,285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,343, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,29,0,0,1812,0,0,8,0,0,0,21,1125,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1327,0,0,0,0,575,1598,0,0,0,0,0,0,0,0,0,895,0,0,0,959,0,0, +0,0,0,1759,173,0,0,0,0,266,261,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,1427,0,0,300,1033,0,0,0,0,0,0,0,0,0,0,0,584,0,0,0,0,52,734, +0,0,217,239,0,1129,0,0,0,0,0,0,0,0,732,20,0,0,0,0,0,0,0,0,0,0,0,418,0,0,0,613,0, +0,0,0,0,0,0,0,0,632,0,0,85,984,0,0,0,0,909,694,7,1109,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,167,0,0,0,0,280,62,0,0,33,0,0,359,186,980,0,0,0,0,0,0,0,0,0,0,0,585,0,0,0, +211,0,0,336,145,0,1130,0,873,0,0,840,263,0,0,0,0,0,0,0,0,0,916,0,0,0,0,0,0,0,0, +0,0,155,0,0,0,461,97,0,0,0,0,0,1356,0,0,0,0,0,0,0,593,0,0,0,0,0,1392,0,0,0,0, +126,0,0,0,0,1179,0,0,0,0,0,162,0,0,0,0,0,765,0,187,0,1286,0,0,0,0,0,0,0,0,0,635, +0,0,23,215,0,0,0,1306,0,0,97,716,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,657,0, +0,0,0,0,0,0,0,299,0,0,0,0,0,0,134,0,0,0,0,0,0,0,0,0,0,0,658,1082,0,0,0,0,0,2002, +0,0,0,0,0,0,833,248,0,0,0,0,0,1654,0,0,531,0,0,0,0,0,0,634,0,0,0,0,0,0,0,0,0, +853,573,249,0,0,0,0,0,0,0,0,527,0,0,0,0,1419,0,0,0,0,0,0,20,49,0,0,0,992,0,0,0, +728,0,0,0,0,0,0,0,0,0,0,0,0,497,1579,0,0,0,0,62,268,0,0,0,0,0,0,0,1201,0,0,0,0, +0,0,0,0,0,0,0,0,495,193,0,0,0,0,106,0,0,859,0,0,23,0,0,0,0,0,0,0,813,925,0,0, +223,613,953,0,0,0,0,0,0,0,0,666,0,0,0,0,0,0,0,0,0,670,0,0,40,216,0,0,0,0,0,0, +259,0,0,0,440,1114,0,0,0,0,0,0,0,0,74,475,0,0,188,139,0,797,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1572,0,0,0,0,39,0,0,0,0,0,0,0,0,0,0,0,0,1594,0,0,0,0,0,0,0,290,0,232, +0,0,887,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,521,14,0,0,0,0,0,741,0,0,0,992,0, +0,0,0,0,0,0,0,111,0,0,425,0,0,0,0,0,789,0,0,0,1593,0,1768,0,0,233,0,0,0,0,943,0, +0,0,0,0,0,0,955,225,245,0,0,0,0,0,0,241,0,0,0,0,1943,0,0,0,1284,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,709,0,0,0,0,0,0,554,0,0,0,0,0,0,0,0,1564,0,0,0, +443,0,0,0,0,0,0,280,0,0,0,0,0,0,0,0,729,0,0,0,348,0,0,0,0,0,0,0,758,848,298,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,829,1422,189,121,0,0,632,812,0,0,556,0,0,0,0,0,436,172, +530,844,232,984,0,0,0,0,0,0,0,0,0,0,147,0,0,0,0,0,0,0,0,537,0,0,0,0,0,859,0,0, +842,0,0,0,0,0,0,0,0,0,0,1291,0,0,0,0,0,0,0,0,0,0,0,1482,612,392,0,0,0,262,31,0, +0,0,0,0,0,0,0,0,0,753,549,0,0,0,0,0,0,696,0,0,0,0,0,0,0,834,0,0,0,0,0,771,0,0,0, +0,0,0,0,0,0,0,0,0,0,921,0,0,0,674,0,0,0,0,0,0,0,0,0,0,308,444,0,0,0,0,0,0,805, +180,0,0,278,271,0,0,214,505,0,1215,0,0,0,0,0,0,387,271,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,1645,42,92,0,459,0,0,330,1557,0,0,0,0,0,0,0,0,113,18,0,0,0, +1742,0,0,0,965,0,0,0,0,0,0,0,0,0,0,0,0,0,182,0,0,65,0,0,0,0,0,0,0,0,0,0,0,0,973, +0,0,0,0,0,328,0,0,588,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,1786, +0,0,962,1985,0,0,0,308,508,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,588,0,0,0,0,0,0,614,793,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,290,0,0,0,0,0,0,0,0,0,0,1136,0,0,0,0,0,0,0,0,0,0,796,719,0,0, +326,210,0,0,0,701,758,472,0,0,0,1947,278,1079,0,0,0,0,0,0,497,41,0,0,634,46,961, +0,810,524,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,532,0,997,0,0,0,0,0,0,0,0,0,0,0,1301,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1298,0,671,0,0,0,306,0,0,0,0,0,0,0,0,0,0, +693,1823,0,0,0,759,0,0,0,0,0,1932,0,0,0,0,0,0,0,0,0,0,0,0,0,0,88,182,0,0,0,1964, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,521,0,0,0,0,0,0,424,857,0,0,0,0,671,328,0, +529,0,0,0,0,0,716,0,1509,80,67,0,0,0,0,59,141,0,0,0,0,0,0,783,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,1498,0,0,0,0,343,430,803,1183,677, +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,1357,53,0,0,0,0,590,0,0,0,0,0,0,0,0,0,0, +0,0,0,329,0,0,0,0,0,0,0,469,0,0,0,0,0,0,0,0,0,0,460,0,0,1743,0,0,963,340,0,0,0, +0,0,1603,0,0,250,0,0,0,0,0,646,218,0,1794,0,0,0,571,0,455,0,0,0,1012,0,0,0,0,0, +0,0,0,0,0,0,0,597,161,0,349,0,524,0,0,0,0,0,0,0,0,0,0,0,0,322,432,0,0,0,0,0,0, +325,223,0,0,0,0,0,566,0,0,0,1394,481,436,0,48,457,610,756,618,0,0,0,755,0,1217, +0,0,0,0,0,197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,544,492,107,414,0,0,0,0,0,0,0,0,0,0,0, +1007,0,0,0,0,5,0,0,1580,0,0,0,0,0,0,0,0,0,0,0,0,0,673,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1843,0,0,0,0,0,0,0,0,0,165,0,0,0,0,0,0,809,885,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,498,0,0,0,306,9,0,0,0,0,0,0,0,437,721,146,0,0,0,0,0,0,0,0,0,0,0,177,0,0,0,0, +0,0,0,1377,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,200,0,959,0,0,0,1928,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1435,0,481,0,0,0,0,0,0,142,84,0,0,0,0,0, +1015,0,0,0,315,0,0,0,0,0,0,759,0,0,0,0,0,0,0,0,712,0,0,0,1722,0,0,0,0,0,0,0,0,0, +0,0,0,222,0,985,1414,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,1273, +538,706,0,0,0,0,0,0,0,0,115,0,0,0,0,0,0,0,0,0,0,1781,0,0,0,0,0,431,97,665,42, +237,0,0,0,264,0,0,213,0,0,0,0,0,0,0,455,0,0,0,906,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +624,0,574,0,0,0,0,0,0,0,0,0,0,0,0,354,0,0,0,1558,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68, +235,723,1813,0,0,0,957,0,830,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,496,0,0,0,0,0,0,0, +547,239,88,0,0,0,0,0,0,0,0,0,1310,0,0,0,0,0,0,0,0,80,1076,0,0,118,0,0,0,479,274, +0,0,0,0,0,0,0,0,0,0,0,497,0,0,669,261,0,0,0,0,13,0,0,0,0,0,0,791,250,642,0,0,0, +1429,939,949,0,0,0,0,0,0,0,0,0,0,0,0,0,818,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,982,330,0,0,0,0,545,0,0,0,0,0,0,947,0,1188,0,0,0,0,0,904,0,0,0,0,0,1372,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,693,377,0,0,0,0,0,0,0,0,0,0,0,0,0,0,695,0,0, +713,386,0,0,0,0,128,1575,0,0,0,0,0,0,424,893,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,904,0,0,0,0,0,552,322,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,1808,49,0,0,0,0, +1832,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,421,0,0,442,415,0,0,289, +0,0,0,0,0,206,110,0,0,0,0,0,205,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +19,1539,0,0,0,0,0,1340,0,1194,0,0,0,0,0,0,0,0,549,0,0,0,0,0,0,0,0,1720,0,0,0,0, +0,0,0,0,0,319,0,0,0,0,112,1180,0,0,0,0,0,0,0,0,0,0,0,967,0,0,0,0,0,0,0,0,0,1940, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,735,0,0,0,0,0,0,0,0,0,897,132,0,0,0,0,0,0,0, +0,0,0,38,838,0,0,0,379,218,8,660,1017,0,0,0,0,0,0,111,387,647,877,0,0,53,790,0, +0,0,0,0,0,0,0,458,0,0,0,0,0,0,954,0,0,0,394,0,1367,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,882,0,0,0,0,0,0,0,1409,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,38,124,342,199,0,0,0,0, +0,0,0,0,0,0,724,628,0,0,0,0,804,266,0,0,0,0,0,208,0,79,0,0,0,0,0,0,0,0,741,0,0, +0,0,0,0,0,0,0,0,606,0,1494,821,1553,0,0,135,405,0,0,178,100,0,0,0,0,0,0,0,0,0,0, +0,0,0,481,0,0,0,1378,0,0,0,0,0,0,0,0,0,0,0,0,0,791,33,1227,857,0,467,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,447,0,0,0,0,0,0,86,128,0,0,0,0,0,0,587,0,0,0,692,1018,0, +195,0,0,0,0,0,0,0,1546,0,0,0,0,0,0,0,0,0,0,0,684,0,0,345,0,0,0,0,0,0,365,0,1683, +0,0,472,0,433,0,0,0,0,0,0,0,28,0,0,0,997,0,705,3,0,0,0,0,0,0,0,0,0,229,0,0,0,0, +102,0,0,0,0,866,1022,0,0,0,0,0,0,0,0,0,55,0,115,0,0,0,0,933,0,0,0,0,0,0,0,702,0, +0,0,0,0,0,0,1728,26,484,0,0,0,185,618,417,0,803,0,0,0,0,0,0,0,0,0,0,0,1262,0,0, +0,0,0,0,0,0,0,0,0,0,0,633,0,0,0,0,0,0,0,0,0,0,0,0,0,479,262,0,0,0,0,0,0,830,0,0, +0,0,26,70,0,0,0,0,0,0,0,0,217,0,640,51,0,0,360,1586,0,0,0,0,0,652,0,0,0,0,0,766, +0,0,0,0,298,737,0,0,0,0,0,0,0,0,0,0,655,222,906,0,0,1013,991,2009,0,0,0,0,503,0, +0,0,216,154,0,0,0,716,0,844,0,0,0,0,621,252,0,0,0,0,748,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,103,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,576,0,0,0,648,0,0,0,331,0,0,0, +0,0,0,0,0,0,0,0,0,632,0,0,0,518,107,0,0,0,0,0,0,0,0,851,0,0,0,0,504,0,0,0,0,0,0, +0,0,0,0,0,0,7,883,0,0,0,0,0,0,0,922,0,0,0,0,0,0,0,0,91,993,0,0,0,0,0,0,200,131, +10,0,0,0,0,0,0,0,0,0,0,0,0,0,365,1433,0,0,0,0,28,103,0,0,798,1013,0,0,0,0,0,0,0, +0,39,1925,0,853,0,0,271,519,0,0,0,0,338,0,0,300,470,419,0,0,0,0,0,0,836,0,0,0,0, +0,0,1937,0,0,0,0,0,393,0,0,357,0,0,0,0,0,703,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,387,0,0,0,0,0,0,75,708,453,1351,0,303,0,0,772,0,0,0,0,0,0,0,0,749,0,0, +0,0,0,0,0,0,0,0,0,0,0,1065,0,0,717,226,0,0,0,0,0,890,431,626,0,0,0,0,706,0,0,0, +51,698,0,0,0,0,0,0,0,0,0,0,0,828,0,0,17,0,0,0,0,1929,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,84,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,871,498,0,101,1793,0,0,0,0,0,0,435,0, +0,0,0,0,966,0,129,1644,0,0,0,0,0,0,0,0,0,0,0,0,0,997,502,0,0,0,0,0,0,0,0,0,0,0, +0,823,0,1927,0,0,0,0,98,1756,0,0,0,0,0,0,0,0,0,0,0,0,8,0,160,1046,0,492,0,0,0,0, +0,0,129,45,0,0,0,0,0,0,353,558,0,0,0,0,0,785,0,0,0,1145,189,0,0,0,26,353,0,0,0, +0,0,2024,0,0,0,606,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,855,0,0,0,0,0,0,0,0,0,0,0, +0,0,2011,0,0,5,4,0,0,461,764,0,0,0,1449,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1445,0,0, +0,1168,0,0,0,233,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,216,0,0,0,286,0,0,0, +3,0,0,0,723,536,0,0,0,0,0,285,0,0,0,560,0,0,0,0,0,690,0,0,0,0,0,1246,0,0,63,0, +33,0,0,0,0,0,520,1862,0,0,0,0,0,0,0,0,0,0,0,0,630,0,0,0,0,554,0,0,0,0,0,1001,0, +0,0,0,0,446,0,0,0,0,0,0,0,1313,0,0,837,636,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,278, +0,0,0,0,0,0,0,0,868,0,0,0,0,1010,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1231,0,304,0,506,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26,0,93,1408,794, +843,704,0,285,114,485,898,145,0,19,2035,0,0,0,1933,0,0,0,0,0,0,0,1728,0,0,0,0,0, +0,0,0,746,0,0,0,0,0,0,0,995,1964,0,0,0,0,0,0,0,0,0,0,0,1550,0,874,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,1018,0,0,0,814,126,0,0,1264,0,0,814,955,0,0,0,0,0,0, +0,981,0,0,0,0,0,0,0,0,915,56,0,0,100,0,0,0,0,0,0,0,0,0,638,0,0,0,0,738,0,0,0,0, +0,0,0,0,0,758,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1112,0,0,214,0,0,0,133,0,196, +168,0,0,0,0,0,1152,0,1245,0,0,538,169,871,1816,0,0,413,133,0,0,0,978,0,0,43,93, +371,0,0,0,0,0,0,526,25,0,754,335,0,0,0,0,182,0,0,0,0,0,0,0,0,0,0,0,39,601,0,0,0, +0,0,0,0,181,370,0,0,1652,358,0,0,0,0,0,0,0,0,0,176,286,0,788,0,0,0,0,0,1223,780, +254,1003,896,0,0,0,1447,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,744,0,0,0,0,0,126,0, +41,788,0,0,0,629,0,0,0,0,0,0,0,0,0,0,0,293,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,420,37,1900,0,0,0,0,542,1570,957,0,0,0,0,0,0, +0,373,31,0,0,0,0,125,325,0,0,0,0,0,0,323,0,0,1547,0,0,0,0,0,0,0,0,0,0,0,0,0, +1216,0,0,0,0,0,0,198,1905,629,15,0,0,0,0,0,0,20,75,543,1353,0,0,0,533,0,0,6,0,0, +0,0,0,0,538,0,0,0,0,0,0,0,0,0,0,0,338,0,0,0,0,11,0,0,0,284,659,0,989,0,0,0,0,0, +0,0,0,0,848,0,0,507,0,0,0,0,0,0,0,0,188,991,884,0,0,0,0,60,959,0,0,0,0,0,1653,0, +0,922,337,0,638,0,0,500,0,0,0,0,0,0,0,0,0,0,0,166,0,0,0,0,0,0,0,0,0,0,0,0,418,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,760,0,0,0,0,0,0,1277,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,770,0,0,0,0,0,0,0,243,89,0,0,0,0,0,0,0,0,0,1396,0, +560,0,0,3,1658,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,586,0,0,1271,0,0,0,505,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1947, +41,445,0,0,0,0,0,0,0,0,57,189,0,0,371,0,0,0,0,552,0,883,0,923,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,875,0,0,0,1788,49,0,0,0,0,0, +0,0,0,0,0,0,661,0,0,1945,0,0,0,0,0,794,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,1135,0,0,0,745,0,0,0,0,0,0,0,84,0,0,0,0,0,0,0,410,0,976,0,0,0,0,0,703,0,0, +0,0,0,0,187,322,0,0,0,227,0,0,0,0,560,0,31,1395,0,0,0,0,0,466,0,0,0,0,643,167,0, +0,0,1428,0,412,0,0,0,0,0,0,0,0,0,1118,562,0,0,0,0,0,256,0,0,0,0,0,0,1771,0,0,0, +0,0,1190,132,0,66,0,0,0,0,0,0,0,0,0,0,317,0,0,0,63,0,0,0,0,0,0,0,1475,0,0,0,0,0, +0,0,288,0,0,0,0,608,0,0,0,0,0,0,0,0,1225,0,1189,0,0,0,0,0,0,0,1468,0,0,0,0,0, +689,120,0,0,0,0,0,0,0,1,0,329,0,0,0,0,226,0,0,0,0,0,1855,0,0,461,0,0,0,0,1346,0, +0,0,0,0,85,0,0,299,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,1171,0,0, +0,980,0,0,0,0,0,0,0,0,637,279,0,0,0,0,0,293,0,0,0,0,528,17,0,0,0,0,5,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,48,0,0,0,0,0,0,0,601,0,0,0,0,0,0,779,0, +196,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1322,737,752,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,412,192,80,0,0,8,1470,0,0,0,0,0,0,0,0,0,873,0,0,0,0,0,835,0,0,0,0,256, +38,986,0,0,0,0,0,0,0,0,0,91,257,278,911,0,0,0,0,0,0,0,0,749,151,0,0,0,0,0,0,0,0, +0,0,0,0,989,0,0,990,0,0,90,194,0,0,0,0,0,425,0,0,0,0,0,774,0,0,0,0,0,0,0,0,0,0, +646,827,752,0,0,0,662,0,22,21,0,0,0,0,0,0,95,239,0,0,0,431,0,0,0,0,0,874,0,0, +265,65,0,0,0,1350,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1887,0,0,0,0,0,0,0,809, +0,696,0,1074,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,630,0,0,802,0,0,0,56,776,0, +970,0,0,797,0,0,0,0,0,400,0,0,1951,0,0,41,0,11,118,0,0,0,0,0,0,0,0,251,615,0,0, +0,1044,0,0,0,0,0,0,0,0,0,0,0,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,370,0,0,0,0, +104,48,209,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,930,0,0,0,0, +0,0,0,0,0,0,0,1286,0,759,0,120,385,0,0,0,429,0,0,0,0,0,0,0,0,820,0,0,0,0,0,0, +199,0,10,151,0,0,0,761,365,0,0,0,0,0,0,0,0,0,46,1086,0,0,0,0,11,1624,58,344,0,0, +1008,1868,0,0,0,888,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,711,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,914,1913,0,958,0,885,0,0,0,0,0,0,0,0,0,0,0, +0,0,847,276,0,302,65,0,0,0,510,0,1514,0,0,0,0,0,0,152,291,0,0,0,0,0,0,0,0,0,0,0, +0,282,589,0,0,0,0,0,0,0,0,0,0,0,0,0,130,0,0,463,42,0,0,0,0,0,372,0,0,0,0,0,0,0, +0,0,680,0,0,0,0,0,0,0,0,977,1997,0,0,0,810,0,0,0,0,0,0,0,0,0,1390,0,0,0,644,0,0, +867,982,0,0,0,0,0,0,0,540,0,123,0,0,0,1978,0,0,0,0,789,623,0,1723,0,1220,0,0,0, +0,0,0,0,480,0,0,0,0,0,0,0,0,0,0,0,888,0,0,0,0,0,0,0,0,0,0,0,0,299,1995,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,788,179,0,0,0,0,0,0,431,156,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,1373,39,80,196,0,0,507,0,0,0,646,0,0,0,0, +0,1214,0,0,0,0,926,0,0,0,1,114,0,0,0,0,0,446,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,490,0,0,0,491,0,1584,0,0,507,250,0,0,0,158, +10,362,1,0,0,0,0,0,0,0,0,0,408,228,860,480,0,779,0,0,0,557,0,0,142,197,0,0,0,0, +0,0,0,0,0,0,0,1490,11,378,316,1057,0,0,18,579,299,1546,0,177,0,0,0,0,0,0,0,0,0, +411,0,0,0,0,727,439,0,0,0,0,0,1528,0,0,0,0,0,0,58,0,482,0,0,0,505,1952,0,0,0,0, +0,0,0,0,0,0,0,242,0,0,0,0,0,0,0,953,0,0,0,0,802,0,0,0,0,0,0,0,0,0,0,290,0,0,791, +52,0,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,1028,0,0,138,0,0,0,0,1811,0,0,0,0,0,0, +934,1821,0,0,0,0,371,38,0,0,0,1296,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,723,0,0,0,0,0, +0,0,0,0,0,0,0,0,1330,0,0,0,0,0,0,0,1255,296,109,0,0,0,0,0,660,0,0,0,0,270,591,0, +0,0,0,0,0,0,1090,81,0,0,0,0,391,0,0,0,0,249,322,0,0,0,0,0,0,0,1412,0,0,0,0,0,0, +0,0,0,0,526,632,0,0,0,0,0,0,235,144,0,0,0,0,0,940,0,0,0,52,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,309,196,0,0,0,0,0,1912,0,1290,0,686,0,0,625,0,0,0,0,0,0,0,0,0,0,0,412,0, +0,0,0,43,0,0,0,0,11,967,758,0,0,0,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,0,0,0, +873,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,890,0,0,2,0,0,0,0,0,0,0,0,1774, +393,263,0,0,0,0,0,0,818,456,0,0,251,178,393,97,0,0,0,0,0,674,168,0,0,0,0,0,0,0, +159,1639,0,0,0,0,0,0,0,0,59,934,0,191,0,0,0,0,346,165,0,877,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,128,0,0,0,0,0,0,1297,0,0,0,0,0,0,164,0,0,0,15,132,241,1073,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,228,324,53,0,0,910,0,0,0,0,0,0,0,0,734,705, +217,73,0,0,0,0,0,0,0,0,636,389,0,1409,0,0,0,0,0,893,0,0,0,0,21,0,0,0,0,0,0,0,0, +0,0,0,0,0,721,0,0,0,959,0,0,0,0,1433,0,0,0,0,0,0,0,0,0,0,0,0,174,189,0,0,0,0,0, +0,0,0,0,0,22,2,0,0,815,354,0,0,0,0,425,0,411,60,13,1611,0,0,0,0,0,0,0,0,0,0,0,0, +0,1478,596,0,0,398,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,1159,0,0,0,0,0, +592,223,0,0,0,0,0,0,0,245,64,0,0,0,0,278,0,604,0,0,1502,265,0,0,0,0,0,0,0,310, +1763,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,129,0,0,0,0,0,0,0,0,0,1356,0,0,0,0,0,0,0, +0,505,0,0,0,0,0,0,0,1000,0,0,966,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,839,0,0,0,0,0,0, +0,0,0,0,0,0,0,637,0,0,0,0,0,0,0,0,0,0,0,0,0,0,590,0,0,0,0,280,0,0,0,1386,0,0,0, +281,0,1064,0,0,0,0,0,917,0,0,15,555,0,0,1014,1883,0,0,0,965,0,0,117,33,0,0,0, +801,0,0,0,0,0,877,0,824,0,0,0,0,0,0,0,0,0,0,0,365,0,0,0,0,0,0,774,7,0,430,0,0, +231,360,0,0,0,0,0,0,0,0,822,740,0,0,929,1485,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,852,0,0,0,0,17,0,0,0,0,0,0,1001,0,0,0,0,35,831,0,0,384,457,0,0,0,1351,0,27, +0,0,984,0,264,552,0,401,0,0,0,710,0,1211,0,0,11,205,0,0,0,0,0,0,0,0,0,0,0,0,5, +579,0,717,0,0,1011,0,0,0,0,0,0,0,0,0,0,0,0,0,0,805,0,0,0,0,0,0,0,0,0,0,0,489,0, +0,0,1024,0,0,0,0,0,0,0,0,0,892,0,0,0,0,0,0,0,0,0,0,0,0,473,0,0,0,659,864,0,0,0, +0,0,0,152,819,0,51,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,0,229,0,0,0,0,674,0,0,0,0,0, +0,0,0,0,770,52,79,0,0,0,1666,0,409,0,0,0,0,0,0,0,195,0,688,0,0,0,0,0,0,0,0,0,0, +0,889,174,160,0,0,0,0,0,0,0,0,0,0,0,0,0,872,0,918,569,268,0,0,0,1224,0,1361,0,0, +0,0,0,0,0,0,0,374,0,0,0,0,0,731,0,0,0,0,190,0,0,0,0,0,0,0,202,506,444,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,835,0,17,1526,0,0,0,0,0,477,0,0, +994,1374,76,0,0,0,0,0,0,0,355,287,0,1389,0,0,0,0,0,0,455,384,0,0,0,264,0,0,0,0, +0,0,0,0,0,0,0,0,1001,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,851,175,359,0,0,0,0,0,0,0, +0,287,740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,857,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +819,1402,0,0,0,0,0,0,174,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1649, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,655,573,0,0,0,0,0,0,0,0,128,351,0,0,0,0,0,0, +0,0,0,0,0,918,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,687,0,0,0,0,0,0,0,0,0,1525, +0,0,0,1009,0,0,0,0,0,0,0,340,0,0,0,0,0,0,0,0,0,0,861,0,176,0,0,0,0,0,0,0,0,0,96, +985,0,615,0,0,0,0,0,0,0,1919,0,0,0,0,0,1131,0,0,0,0,0,0,0,247,0,0,0,0,27,23,0,0, +0,0,0,0,0,0,38,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1015,0,0,0,0,0,1088,0,0, +0,0,0,1585,0,0,0,0,227,0,0,0,478,360,0,0,0,95,0,0,0,0,0,0,699,0,0,0,26,0,0,0,0, +1119,0,0,0,739,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,741,67,0,0,0,0,0,0,464,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,0,96,0,0,0,26,342,0,0,0,0,0,0,203,0,0,449,0, +0,0,0,0,0,0,0,0,0,256,311,0,0,0,0,0,0,758,0,0,0,0,0,0,0,0,827,0,0,0,0,581,64,0, +1047,0,0,0,0,0,288,0,0,0,0,0,1375,0,0,0,0,0,0,0,0,0,0,0,1309,0,0,0,0,0,0,0,0, +376,12,0,0,0,0,0,154,0,1520,0,1753,95,502,0,0,0,0,0,0,0,269,291,1197,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,15,0,0,0,0,1341,0,1017,0,0,0,0,0,0,0, +0,857,1810,533,0,0,1453,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,836,211,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,19,0,156,0,0,0,0,1009,0,0,0,0,0,0,0,0,0,0,0,0,0,820,0,0, +0,0,0,0,0,0,0,228,0,0,0,1131,0,1276,0,0,0,0,0,0,0,0,0,0,0,0,849,1792,0,0,389, +291,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,525,0,0, +0,453,0,0,0,0,666,0,0,0,422,0,355,0,0,0,0,165,0,260,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,865,0,0,0,0,0,0,0,1625,0,0,0,234,0,1383,0,0,0,0,0,0,0,0,306,0,0,0,802,1921, +0,0,0,0,0,0,180,0,0,0,0,1312,814,0,0,0,0,0,0,0,0,0,0,707,0,0,0,1493,11,61,733,0, +0,0,341,0,0,0,98,0,0,0,0,0,0,0,0,0,0,0,1014,0,0,0,0,0,0,0,142,102,0,0,30,0,0, +823,0,1045,0,0,0,1930,0,1512,0,0,0,0,0,0,0,87,0,1243,245,0,0,0,0,0,0,0,48,68,0, +0,0,0,0,0,0,0,126,77,625,938,0,0,351,0,0,0,174,1668,0,707,0,0,0,0,0,0,0,0,0,0,0, +403,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,282,0,0,0,0,0,0,8,44,0,0,363,115,0,0,0,0,0,0, +0,0,0,0,0,0,545,761,0,0,835,1254,0,0,0,0,930,1936,0,0,0,0,0,0,0,0,653,0,0,0,0,0, +344,0,0,1483,673,185,0,0,460,93,753,478,0,0,0,0,0,1020,0,0,0,0,0,0,0,103,0,0,0, +499,0,0,0,0,0,0,207,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,968,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,3,0,0,0,0,399,0,0,0,0,224,563,0,0,0,0,0,704,0,0,0,0,0,0,0,0,0,0,0, +1559,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,861,0,0,0,0,946,333,746,0,0,0,0,0, +0,0,910,0,0,0,0,0,0,0,0,0,0,0,0,0,652,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1393,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1514,0,0,0,0,201,0,510,717,0,0,528,0,0,0,0, +20,0,0,0,1251,0,0,0,1163,0,0,0,307,0,0,0,0,0,1091,0,0,0,0,0,0,0,0,0,0,0,429,0,0, +0,881,0,0,0,0,0,621,0,0,0,0,0,0,0,736,0,348,0,868,0,0,0,0,433,0,0,0,771,1495,0, +0,0,0,215,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,55,0,0,0,0,0,0,0,112,62,0,856,270, +0,572,0,0,0,0,939,0,0,0,0,0,0,0,352,0,0,0,0,0,0,0,0,0,647,0,0,0,0,10,0,0,0,0,0, +0,0,220,0,0,0,0,0,0,0,0,0,0,0,0,0,464,0,0,109,0,0,0,1746,0,0,0,515,0,0,0,566,0, +0,0,0,0,0,67,40,0,0,722,992,0,0,923,0,0,0,0,0,0,1145,0,0,0,0,0,0,0,0,0,0,0,568, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,247,0,0,0,0,645,0,0,328,0,0,0,0,0,0,0,0,0,0,0,0, +1363,0,0,0,0,0,1280,0,0,0,0,0,0,0,0,0,0,7,28,360,162,0,0,0,0,0,0,0,0,0,0,0,764, +0,0,833,862,0,856,0,0,0,0,0,0,736,92,0,0,948,1944,0,1479,63,590,0,0,0,1521,0,0, +0,709,0,0,61,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,483,0,0,0,0,1213, +0,0,0,0,29,1022,0,1712,0,466,0,0,0,0,0,0,0,0,0,0,0,0,0,731,0,0,0,0,0,0,171,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,241,0,0,0,0,0,0,0,0,0,0,0,964,2005,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1100,0,0,0,954,0,0,0,0,0,0,0,0,0,1958,0,0,34,549,994,0,0,449, +137,850,0,0,670,146,0,0,0,0,518,159,0,0,0,0,0,0,0,0,151,0,0,1027,0,0,0,0,0,0,0, +0,0,0,983,0,0,0,0,993,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,141,501,0,0,0, +0,0,0,0,0,0,452,0,0,0,0,0,0,0,0,0,0,233,149,0,0,0,0,0,0,0,0,582,0,0,0,801,0,0,0, +0,0,0,70,0,0,369,0,36,0,0,0,0,0,0,0,204,721,430,241,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,1817,16,1078,1021,0,0, +406,0,0,0,0,0,69,0,0,0,0,0,1830,0,0,0,824,0,0,0,0,0,0,0,0,0,826,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,816,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1000,717,1845,0,423,0,0, +0,0,0,0,0,0,510,0,0,1048,0,0,0,618,0,0,0,520,0,0,0,0,990,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,321,0,0,0,0,0,0,0,1135,0,0,921,0,0,0,24,397,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,856,0,0,0,139,282,981,0,288,0,0,0,1890,651,56,0,0,0,0,0,0,0, +0,261,0,0,0,0,0,0,0,0,0,0,0,617,1403,0,1205,0,0,563,0,0,0,0,0,0,0,0,333,0,0,0,0, +0,369,0,0,0,0,0,0,0,0,0,622,0,0,0,1407,0,0,0,0,0,0,0,0,0,0,0,0,624,160,0,363,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,619,0,174,292,0,0,656,616,0,0,0,685,0,0,0,0,0,0,0,0,0,0,0,0,0,647,0,0,0,631,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1267,0,0,0,1797,0,0,0,1684,0,0,469,0,531, +1230,73,0,0,0,0,0,0,0,0,0,268,0,0,0,0,0,102,558,109,65,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,595,0,0,0,0,0,374,1832,0,0,0,0,0,0,16,0,405,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,881,0,1495,0,0,0,0,0,0,0,0,0,142,0,0,0,0,0,0,0,0,0,0,21,466,23, +257,0,0,0,0,0,0,77,404,0,0,0,0,0,0,712,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,860, +1848,0,0,652,629,0,0,0,0,13,377,0,1842,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1501,0, +0,0,1906,0,0,0,0,0,0,0,0,0,0,0,0,0,491,234,171,0,0,0,0,631,1186,0,0,0,0,0,0,0,0, +0,0,0,0,931,0,170,0,0,0,0,0,0,0,0,0,0,1587,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +765,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,424,0,0,714,0,0,0,0,685,0,0,0,0,0, +0,285,0,0,0,0,0,0,429,0,0,0,0,0,0,0,0,0,0,71,18,0,0,0,0,0,0,0,0,0,0,116,828,0,0, +0,0,0,0,289,0,0,0,0,0,0,0,0,675,0,0,0,1424,0,0,0,0,0,647,0,0,0,1334,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,36,209,0,0,0,0,0,0,0,342,0,0,0,928,0,0,0,0,0,1838,118,856,654, +318,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,915,895,454,0,0,513,1425,0,0, +0,0,0,0,791,0,153,0,0,0,0,0,0,796,909,445,345,0,0,0,0,0,0,0,0,578,0,0,0,1387,0, +0,0,555,0,0,0,0,0,0,766,0,0,0,0,0,0,0,0,0,0,541,0,0,0,0,0,0,0,0,0,0,0,0,0,880,0, +0,0,0,0,1506,0,0,983,0,768,0,0,0,0,584,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,737, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,30,426,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +117,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,462,0,0,0,385,0,398,0,0,0,0,0,0, +0,0,0,347,0,0,0,0,125,1259,644,136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,469,0,0,0,0,0, +1367,0,0,0,0,0,0,0,0,0,0,0,719,0,0,0,0,0,0,0,0,0,0,0,0,0,1423,0,0,0,0,0,0,0,0,0, +749,0,0,0,0,546,645,0,0,0,0,0,0,277,0,0,1275,0,0,0,0,0,0,0,453,536,555,0,0,987, +1107,0,0,90,0,0,0,0,0,0,0,0,860,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +257,0,1768,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,83, +0,835,0,0,0,0,0,0,0,2006,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,696,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,95,1718,0,0,0,0,0,0,0,26,0,550,0,0,0,0,0,901,0,0,0,0,0, +0,822,0,0,122,0,0,0,807,0,0,0,0,0,262,0,620,601,34,0,0,170,0,0,0,0,537,0,0,0,0, +0,0,0,0,0,332,0,0,208,1909,182,261,0,0,0,1721,0,0,0,0,0,933,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,1609,0,895,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,812,0,0,942,1916,0,0,0,0, +0,0,0,778,0,0,0,137,0,1314,0,0,0,0,0,0,0,1661,0,0,0,0,0,0,0,1591,0,0,0,0,0,0, +820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,185,89,0,1160,230,6,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,63,29,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1740,0,0,177, +170,0,1961,0,0,0,0,0,0,0,0,0,0,0,0,91,0,17,44,0,0,0,0,0,0,0,0,0,270,0,296,0,0,0, +0,0,0,0,1523,0,0,0,0,0,0,0,0,0,0,757,7,0,0,0,0,0,0,0,0,0,0,530,588,0,0,0,0,0,0, +0,0,0,786,0,0,0,0,0,580,627,88,447,57,0,0,0,0,0,0,0,0,845,735,0,0,0,0,0,31,15,0, +460,521,12,424,0,0,0,1302,0,0,0,0,0,0,0,595,0,0,0,13,548,97,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1472,452,1767,0,0,0,0,0,0,0,0,0,0,115,0,0,0,0,0,0,1543,0,1111,0,0,0,0, +1,0,359,488,0,267,0,0,0,1983,0,0,0,0,0,0,0,1155,0,1575,0,1438,31,0,0,377,101,0, +0,0,0,0,0,0,0,0,0,0,0,0,476,0,0,0,0,0,0,0,0,2023,0,0,0,0,0,1836,0,0,0,0,35,843, +0,0,0,0,0,0,0,554,0,0,0,536,625,207,0,1371,0,0,0,424,785,336,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,896,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27,750,0,0,0,0,238,0,0, +0,0,0,383,0,0,0,0,0,0,0,0,603,725,11,0,0,0,0,0,0,0,0,0,476,0,0,0,0,0,1552,0,0,0, +0,0,0,0,680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,435,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1431,0,0,13,112,0,0,356,0,0,0,0,0,0,0,0,0,0,1963,0,0,0,1244,18,0,0,0,0,0,0,867, +0,0,0,0,0,0,50,708,73,592,0,502,0,0,0,0,0,0,161,347,0,0,0,0,470,33,0,246,571,10, +0,465,614,0,237,0,0,0,0,0,24,18,0,506,0,0,0,0,0,0,33,309,0,0,0,0,0,0,0,0,0,0, +140,0,0,0,0,1056,0,0,0,1704,0,0,0,0,0,0,0,1036,0,0,0,0,0,0,0,0,0,1315,432,86, +264,524,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,107,0,0,0,0,0,123,927,0,0,957,1149,0,0, +0,0,0,778,0,502,196,0,0,0,0,1312,0,0,0,0,0,0,0,855,0,0,0,0,0,0,0,0,0,0,45,1400, +0,0,0,1003,0,0,0,0,0,1097,0,0,0,0,0,0,0,0,545,612,0,0,0,0,0,0,0,0,0,0,0,0,54,0, +0,0,0,172,0,0,0,1029,0,0,0,0,0,0,0,0,0,568,0,0,0,732,617,0,0,974,94,989,733,0,0, +0,0,0,0,1789,0,0,665,2015,0,0,0,0,0,0,806,287,0,0,0,0,0,1539,0,0,0,0,0,0,0,0,0, +0,182,1563,0,0,0,0,0,0,0,0,0,484,0,0,0,0,0,1623,0,0,0,0,0,0,0,0,878,1833,0,1569, +0,0,0,0,0,0,0,0,93,0,715,994,0,0,0,0,0,63,0,591,0,0,0,0,0,0,0,749,0,0,0,0,547, +366,0,0,0,1747,0,0,0,0,0,0,0,89,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1463,0,772, +893,0,0,0,48,0,0,941,0,0,690,1785,106,440,0,0,0,0,0,0,0,0,0,0,32,0,332,216,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,852,0, +0,416,564,0,918,0,1764,0,0,3,0,0,274,0,0,0,0,501,0,0,0,0,0,0,0,851,743,0,49,0, +879,0,0,47,0,0,0,0,0,0,865,0,1202,0,0,0,0,0,0,47,272,0,0,0,0,0,0,0,0,0,0,0,1455, +0,0,0,0,891,1911,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,761,0,0,0,0,0,0,0,0,0,407,0, +183,0,0,490,0,0,0,0,0,0,0,35,731,0,0,0,0,0,0,0,819,0,0,0,0,0,0,0,0,0,0,0,0,0, +575,0,0,0,0,45,818,0,0,77,222,0,0,0,0,849,1880,0,0,0,633,0,1308,0,0,0,0,0,0,0,0, +0,0,86,0,0,0,0,0,0,0,0,0,0,0,0,0,0,817,0,0,0,0,0,0,0,0,0,882,0,0,0,914,0,0,0,0, +0,0,0,0,0,0,865,0,0,426,399,58,0,0,0,0,0,0,538,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,876,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,139,566,0,63,12,0,0,0, +0,0,0,0,0,0,0,0,0,0,3,114,0,0,0,0,0,0,0,0,576,0,0,0,0,0,0,0,0,933,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,692,0,0,0,0,0,0,0,0,0,0,0,0,752,0,0,0,0, +0,0,0,0,375,0,1011,0,0,96,0,0,0,0,0,0,0,0,0,148,0,0,0,0,0,0,0,0,0,0,0,337,56, +666,0,246,394,0,0,0,0,0,0,0,0,437,0,0,0,506,0,0,0,0,1003,0,1163,0,328,0,0,0,0,0, +0,0,0,1000,0,0,0,0,0,744,101,0,0,0,0,0,726,0,0,176,0,146,9,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,839,0,0,0,0,0,0,223,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,246,1931,29,0,0,1771,0,0,0,0,0,846,6,157,0,0,0,0,0,0,0,0,0,875,0,0,477, +773,177,639,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1747,0,0,0,0,158,873,0,659,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,391,0,0,0,0,0,0,0,0,0,0,0,0,668,883,0,78,628,0,0,0, +0,0,0,0,0,0,0,0,0,1460,0,962,0,0,0,0,0,460,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,199,0, +0,0,388,474,0,271,0,333,608,0,0,0,0,0,0,49,0,988,0,707,617,0,0,0,0,0,0,0,756,0, +0,0,0,0,1583,0,0,0,0,0,0,0,0,0,0,285,0,0,0,0,0,0,0,0,0,0,0,0,0,0,344,0,0,0,0,0, +0,0,0,515,1709,0,0,0,0,0,0,0,0,404,0,0,0,0,500,0,0,0,0,0,0,0,0,0,68,216,0,0,0,0, +0,0,0,488,353,0,0,177,236,0,0,458,490,0,0,0,0,0,0,756,1504,0,757,0,1735,0,0,108, +598,0,0,0,0}; +const BROTLI_MODEL("small") +uint8_t kStaticDictionaryHashLengths[BROTLI_ENC_NUM_HASH_BUCKETS] = { +8,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,12,0,0,0,0,4,22,5,0, +4,0,0,0,0,0,0,0,0,0,0,0,0,14,6,0,0,0,5,0,0,0,0,0,0,0,7,13,0,0,4,0,0,0,0,0,0,0,0, +0,6,0,0,0,0,8,0,0,0,0,0,0,7,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,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,12,0,0,4,0,0,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,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,6,0,0,0,0,0,0,0,0,10,4,0,5,13,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,8,7,0,0,9,0,8,0,0,0,0,0,0,6,0, +0,9,0,0,0,11,0,0,6,8,7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,6,8,0,0,0,0,0, +0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,0,0,0,8,4,13,7,0,0,0,0,0, +7,0,5,0,0,0,0,8,5,0,5,0,0,8,7,0,0,0,0,0,0,0,0,0,0,9,0,0,0,8,0,0,0,10,4,0,5,0,4, +0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,8,7,0,4,9,4,0,0,0,0,0,0, +9,0,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,7,18,0,0,0,0,4,9,0,0,4,0,6,0,0,0,6,0,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,8,7,0,0,0, +0,9,0,0,0,0,0,0,0,8,6,10,6,0,0,0,4,0,6,8,6,0,0,0,4,0,0,0,0,0,5,0,0,0,6,0,0,0,0, +10,0,12,7,0,0,0,0,0,4,0,0,0,0,0,5,0,0,8,7,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,0,0,0,0, +0,0,0,0,6,11,0,0,0,0,0,0,0,0,0,8,7,0,0,10,0,0,0,0,0,0,0,0,6,10,0,17,0,8,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,8,6,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +7,0,0,11,4,0,5,0,0,0,0,0,0,0,0,0,0,10,5,0,6,8,5,0,0,0,0,0,0,0,0,0,0,11,5,0,0,0, +0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,9,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,0,0,0,0, +0,0,0,0,0,0,5,0,0,0,6,0,0,10,0,0,0,20,0,0,0,0,0,0,0,0,6,9,5,0,0,0,0,10,4,8,0,0, +4,13,0,0,0,0,0,0,0,9,0,9,0,0,0,0,0,0,0,0,0,0,0,0,4,8,6,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,12,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,12,5,0,0,10,4,10,7,13, +0,0,0,0,0,0,0,0,6,0,6,0,6,0,0,0,0,0,0,19,0,0,4,12,6,9,0,0,0,0,4,0,4,11,0,0,0,0, +0,0,0,12,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0, +0,5,0,0,0,0,0,6,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,9,6,0,0,0,0,0,4,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0, +6,0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,6,0,0, +0,0,0,5,0,0,0,0,14,4,0,0,0,4,12,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,6,0, +0,0,0,0,0,12,0,9,6,0,0,0,0,13,0,0,5,0,0,0,0,0,4,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,13,0,9,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,8,7,8,4,0,0,0,0,0,0,0,0,0,0,0,7,0,7,0,0,0,4,0, +0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,6,8,4,0,0,0,0,0,6,0,7,0, +0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0,0,9,5,0,0, +0,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,9,4,0,0,0,0,0,0,0,4, +12,5,11,0,0,0,0,0,0,0,0,0,8,7,0,5,0,0,8,7,0,5,0,0,0,0,8,0,0,0,0,7,0,4,10,0,0,0, +0,0,0,0,9,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, +13,5,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,14,5,0,0,0,7,0,0,10,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,6,0,4,0,5,0,0,0,0,8,5,0,0,0,0,0,0,9,5,9,0,0,0,0,0,0,0,0,6,9,0, +0,4,0,0,0,7,0,0,0,6,0,0,10,4,0,0,0,0,0,6,0,0,10,0,0,0,8,5,0,0,0,0,0,0,0,0,10,0, +0,0,0,0,18,4,12,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,7,0,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,4,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, +0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,8,0,0,0,0,0,0,6,0,0,0,4,10,5,0,0,0,0,0,0,0,0,0,0, +0,4,8,7,0,0,8,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0, +0,0,0,8,6,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,8,7,0,0,0,0,8,0,12,6,0,6,0,0,0,0,9,7,11,7,0,0,0, +0,0,0,0,0,0,0,0,0,11,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,10,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0, +0,0,0,6,0,0,0,7,0,4,14,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,14,0,0,0,0,0,8,4,0,4,0,0,0,5,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,20,0,0,4,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,12,5,0,7,0,5,0,0,10,0,0,7,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,6,0,4,9,7,0,0,0, +0,0,7,0,0,0,0,0,0,10,0,9,0,9,0,0,0,0,0,0,0,0,4,9,0,0,0,0,6,0,0,0,0,0,0,0,0,11,4, +0,6,0,0,0,0,0,0,8,0,8,0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,0,0,0,0,0,13,6,0,0,11, +0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,6,18,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0, +0,5,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,0,0,9,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,11, +4,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,4,0,4,0,0,0,0,8, +6,0,0,0,0,0,0,9,6,0,0,0,0,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0, +0,6,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,6,0,6,0,0,10,6,0,0,0,7,0,0,8,0,8,7,0, +0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0, +0,0,0,8,7,0,0,0,0,0,0,0,0,12,0,12,0,0,0,11,6,0,5,0,0,12,0,12,5,0,7,11,6,0,0,11, +0,0,0,12,0,0,4,12,7,8,6,0,0,0,0,8,5,0,0,0,0,0,0,0,4,11,0,0,6,0,7,0,0,0,0,0,0,0, +5,0,6,0,0,0,0,8,0,10,0,0,0,0,0,0,0,0,0,0,0,9,7,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,0,10,0,0,5,0,0,12,6,0,0,0,0,0,0,10,6,0,0,0,0,8, +6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,5,0,0,0,0,11,0,10,6,0,0,8,6,0,0,0,6,0,7,10,6,0, +0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,10,7,0,0,0,0, +10,6,0,0,0,0,0,0,8,5,11,0,8,4,0,0,0,4,0,0,0,0,9,4,8,0,0,0,0,0,0,0,11,6,0,0,0,0, +10,7,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,9,6,0,5,0,7,0,0,0,0,0,7,0,0,11,0,0, +0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,0,13,0,8,6,13,0,0,0,11,7,0,7,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,0,9,6,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0, +0,0,0,0,0,5,9,0,0,0,0,0,0,0,0,0,0,4,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,9,7,0,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0, +5,11,5,0,0,0,0,0,0,0,0,0,4,0,7,0,6,0,0,0,6,20,0,0,0,10,7,0,5,14,4,0,0,0,0,0,0,0, +0,0,6,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0, +0,0,6,0,4,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,11,6,15,0,0,0,0,0, +10,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,7,0,0,0,0,0,0,0,0,9,7,13,0,0,0,0,0, +0,7,0,0,8,6,0,0,0,0,0,0,0,0,9,4,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,5,0,0,0,0,0,0,0,0,0,0,0,0,8,5,0,4,0,0,0,0,0,0,0,0,0,0,12,6,8,0,12,0,0,7,0,0,0, +0,0,5,10,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7, +14,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,8,7,10,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,18,6, +14,7,0,0,0,0,0,0,0,0,11,6,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,11,7,0,0,10,7,0,0,0,6,8,6,0,0,0,0,0,0,0,6,0,0, +19,0,0,0,9,5,0,0,0,0,0,0,11,7,0,0,0,7,0,6,0,0,11,0,0,0,0,4,8,0,0,0,0,0,0,0,0,6, +0,0,0,0,0,6,0,0,8,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,7, +0,7,0,0,0,7,15,0,0,5,0,0,0,0,10,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,7,0,0, +0,0,0,0,0,0,9,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +11,7,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0, +0,0,5,0,4,0,0,0,4,0,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0,11,6,0,0,8,5,14,0,0,4,0,0,0,7, +17,0,0,0,0,0,0,0,13,5,0,0,0,0,0,5,0,0,0,5,0,0,0,0,16,6,0,4,0,0,0,0,0,0,12,0,0,0, +0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,5,0,5,0,6,10,0,12,0,0,0,0,0,0,0,0,7,0,0,0,0,8,4, +0,0,0,0,0,0,0,0,0,0,8,7,0,0,8,0,0,0,8,0,0,6,0,7,0,0,0,5,0,6,0,4,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,22,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,18,0,0,0,9,4,0,0,8,0,9,7,0,0,0,0,0,0,8,6,0,0,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,9,7,0,0,0,6,0,0,14,0,0,0,0, +0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,7,10,4, +0,6,0,0,0,0,0,0,8,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,6,0,0,0,0,0,0, +0,0,11,6,12,7,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,0,9,6,11,6,0,0,0,0,9,5,0,0,0,0,0,0, +0,6,8,5,0,0,0,0,8,0,10,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9, +5,10,7,0,0,0,5,8,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,4,8,7,0,0,0,6,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,22, +0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,5,0,0,0,0,0,0,0, +0,0,0,0,0,17,0,0,6,0,6,12,4,19,6,0,0,0,0,16,0,0,0,0,7,15,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,4,10,4,0,0,8,7,0,7,0,0,9, +4,0,6,0,0,0,4,0,5,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,10,0,0,0,0,0,11,7,0,0, +0,0,12,6,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8, +0,0,0,0,0,0,0,0,0,10,4,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,8,7,0,0, +0,0,0,0,0,6,0,0,0,4,0,0,11,4,0,0,12,7,0,0,0,0,9,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0, +4,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,9,4,0,6,0,0,0,0,0,4, +0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,7,9,6,0,7,0, +0,0,0,0,0,0,6,0,0,0,0,8,6,0,0,0,0,10,6,11,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,5,0,4,8,0,0,0,0,0,9,7,0,0,0,0,0,0, +13,5,0,0,0,0,8,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,5,0,0,11,7,0,0,0,0,0,0,8,6,0, +0,0,0,0,7,0,4,0,0,0,0,0,0,0,5,0,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,10,4,9,0,0,0,0,0, +0,4,0,0,0,0,10,5,10,7,0,0,0,0,0,0,0,0,16,7,0,0,0,0,0,7,0,0,0,0,11,0,0,0,0,0,0,0, +0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,4,0,0,0,7,0,0,0,0,0,0,13,0,0, +0,0,0,0,0,0,0,0,7,0,4,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,13,7,0,7,0,4,16,0,0,0,0,6,8,7,9,7,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0, +0,6,0,0,8,5,0,4,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,11,7,0,0,11, +0,0,0,0,0,9,5,0,4,0,0,0,0,9,7,8,6,0,0,0,0,0,0,10,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0, +0,7,0,0,0,0,0,0,0,0,0,0,0,4,10,6,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,0,10,7,10,0,0,0, +0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,6,8,7,12,4,0,0,0,0,0,0,0,5,14, +0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,20,4,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,0, +0,6,15,0,0,6,0,0,0,4,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,12,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,5,0,0,0,0,0,0,8,6,0,0,18,0,0,0,10,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,9,6,0, +6,0,0,0,0,0,0,0,0,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,9,0,9,0,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,9,5,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,7,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,4,8,0,8,0,0,0,16,0,0,0,0,0,0,0, +0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,0,0,0,11,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,0,11,0,0,0,9,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,7,0,6, +0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,0,0,0,0,6,0,0,18,0,8,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,7,0,4,0,0,0, +0,0,0,0,0,0,0,8,0,0,0,0,0,16,0,0,0,0,0,16,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,18,0,0,0,0,0,0,0,0,0,9,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,4,0, +0,0,0,0,0,0,0,9,4,0,0,0,0,12,5,0,0,0,0,0,0,0,7,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,6,0,0,0,0,0,0,0,0,0,0,0,0,12,5,0,0,0,0,0,0,0,5,0,0,10,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,9,0,0,0,11,0,0,6,0,6,0,0, +0,7,0,0,0,0,0,0,8,0,0,0,0,6,0,0,0,0,0,0,19,0,0,0,12,0,9,0,0,0,0,0,10,7,0,0,0,0, +0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,16,7,12, +0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,10,5,0,0,0,0,0,0,0,4,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,4,0,0,9,0,0,0,8,0,12,4,0,0,0,0, +0,4,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,8,7,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,9,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,5,0, +0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,8,6,0,6,0,0,0,0,0,0, +0,4,0,0,0,0,0,6,0,0,9,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,10,6,0,0,0,0,8, +6,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,7,0,6, +10,7,0,0,10,5,11,6,0,0,0,0,0,7,16,0,0,0,0,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0, +0,0,0,0,0,8,7,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +8,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,12,7,0,7,0,0,0, +0,0,0,0,6,0,0,0,0,9,0,0,0,23,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,4,0,0,11,7,10,0,0, +0,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,7,0,0,8,7,8,0,0,0,0,0,0,0,0,0,0,0,14,5,0,0,0,0, +0,0,0,0,18,6,8,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,11,0,0,0,9,7,12,6,0,0,0,0,0,0,0,0, +0,0,12,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,7,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,8,7,0,0,0,6,10,0,0,0,9,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,6, +10,7,0,0,0,7,0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0, +0,0,0,8,7,8,6,0,0,11,7,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,4,8,7,0,0,0,0,0,0,0,0, +0,5,0,0,13,0,0,0,0,5,0,0,9,7,0,0,0,0,0,0,0,4,0,0,11,0,0,7,0,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,0,12,7,19,0,8,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,10,6,8,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,7,0,0,12,0,0,0,0,6,9,6, +14,0,0,0,0,0,0,6,0,5,0,0,8,7,0,0,0,6,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,4,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0, +7,0,0,10,0,9,7,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,0,0,0,0,5,0,6,0,0,0,0, +0,0,0,0,0,0,0,6,0,0,0,0,9,7,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0,0,11,7,0,0,13,7, +0,0,0,0,0,0,0,0,12,0,0,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,11,5,0,5,13,0,8,0, +0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,11,5, +9,6,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,10,0,0,0,8,5,0,0,9,0,0,0,8,7,9,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,0, +0,11,0,13,6,0,0,9,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,5,21,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,5,0,0,0,0,0,0,0,0,10,0,8,0, +0,6,0,0,0,4,0,0,9,0,0,0,0,0,0,0,0,0,0,4,0,0,8,6,0,6,0,7,10,0,8,4,0,4,0,0,0,0,0, +5,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,6,12,0,0,7,0,0,0,5,0,0, +0,0,0,0,0,0,0,6,0,0,8,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +15,7,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,24,7,0,0,0,0,0,0,0,0,0, +7,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,4,12,0,0,7,0,0,0,0,0,5,0,0,0,0,0,0,0,0,15,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,8,7,0,0,0,0,0,0,0,0,0,0,8,0,0,0, +0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,9,0,9,6, +0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,8,4,0,7,0,0,0,0,0,0,0,0, +22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,4,0,7,0,0,21,7,0,7,9,6,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,8,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,23,0,0,0,0,7,0,0,0, +4,0,0,0,0,0,0,0,0,9,4,11,7,0,5,0,0,0,0,11,0,0,4,20,0,0,0,0,0,0,0,0,0,0,0,11,5,0, +7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +21,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,11,6,0,0,0,0,0,0,0,0,9,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,5,0,4,9,4,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,4,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,9,0,0,0,0, +0,0,0,10,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,7,0,0,11,7,0,0,0,0,0,0,0,4, +0,4,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,7,0, +0,0,0,0,0,0,0,0,6,0,0,21,6,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,14,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,8,0,0,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0, +0,0,0,8,7,0,0,11,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,7,13,7,10,4,0, +0,0,6,0,0,0,0,0,0,0,0,0,5,10,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0,0,8,4,0,0,0,0,0,6, +0,0,0,0,0,0,0,0,0,0,12,7,0,6,0,0,10,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0, +0,0,0,0,7,0,0,8,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,10,5,0,6,0,0,0,0,0,4,0,0,0,0, +0,0,0,0,0,4,0,0,0,0,9,0,11,4,0,0,0,6,0,0,0,5,12,7,0,5,0,0,0,0,0,4,0,0,0,7,0,0,0, +0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,13,6,10,0,0,0,17,0,0,4,0,0,0,0,0,6,0,4,0,5,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,11,7,0,0,0,7,0,0,0,6,0,0,0,0,0,0, +0,6,0,4,0,0,0,0,8,0,0,0,0,5,0,0,0,0,0,4,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,9,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,0,0, +0,0,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,16,4,0,0,11,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +8,7,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,8,6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10, +7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,12,5,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0, +5,18,7,0,0,14,0,0,0,0,0,0,0,9,4,0,7,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,6,0,0,0,0,0,0, +8,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,7,0,0,0,0,0,0,11,0,0,0, +10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,14,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +11,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,14,6,0,0,0,0,11,4,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,10,7,0,6,0,0,9,0,9,5,0,0,0,0,0, +0,0,0,10,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,8,5,0,0,0,0,0,0,0,0,0,0,11,4,0,6, +0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,12,4,0,6,8,6,0,0,0,0,0,0,0,0,0,0,8,0,0,5,0,0,0,0,0,0,0,7,0,0,13,0,0,0,0,0,0,0, +0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,12,7,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,13,4,0,7,0,0,0,7,0,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,0,0,0, +9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,10,6,21,5,0,0,0,0,8,0,0,0,0,4,0, +7,0,0,0,0,0,0,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0, +0,7,9,6,11,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,7,10,0,0,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,19,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,18,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,9,4,10,4,0,7,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,9,7,9,7,10,4,0,7,0,0,0,0,0,0,0,6,12,0, +0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, +0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,8,0, +0,0,0,0,0,5,0,0,8,7,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0, +0,0,0,0,4,0,0,8,0,0,6,0,0,0,7,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,7,9,7,0,0,0,4,8,0,0,0,0,6,11,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,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,13,4,0,0, +12,6,0,6,0,0,0,0,8,7,0,7,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,4,0,0,0,0,0,0,0,0,0,0,9, +7,22,0,0,0,0,4,0,0,0,0,0,6,0,0,0,4,0,0,9,0,0,6,0,0,24,7,0,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,10,6,0,5,0,0,0,0,0,0,0,7,0,0,8,0,0,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,7,0, +7,0,0,0,0,0,0,13,4,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,18,0, +0,0,0,0,0,7,12,0,9,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,4,0,0,0,7,0, +0,0,0,8,7,0,0,0,0,0,0,0,0,0,4,18,0,0,0,0,0,10,0,0,5,0,0,11,0,0,0,0,0,0,5,0,6,0, +0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0, +4,0,0,0,0,0,0,10,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0, +0,0,0,5,8,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,20,7,0,0,0,0,0,0,0,0,0,0,0,4,9,0,12, +6,8,0,14,7,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,10,0,0, +0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,9,6,0,7,12,0,0,0,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7, +0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,0,9,0, +12,6,0,5,0,0,0,6,0,4,0,6,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0,0,8,0,0,0,0,4,0,0,0,0, +10,0,0,0,0,0,0,0,8,6,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,12,6,20,5,0,0,0,0,0,0,0,0,0,0,0,0,9,5,0,5,0,0,0,6,13,7,0,0,0,0,15,6,0,0,0, +6,0,0,13,7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0, +10,6,0,0,0,0,0,6,0,0,0,0,9,0,0,0,0,0,19,6,0,0,0,0,0,0,0,0,0,0,13,0,11,0,0,0,0,0, +0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,0,10,0,0,6,0,0,0,0,8,0,0, +0,9,0,15,4,0,6,0,0,0,0,0,6,12,0,0,0,0,0,0,0,14,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0, +0,0,0,0,0,8,7,0,0,0,0,0,6,10,0,0,0,0,0,0,0,0,7,8,4,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,9,7,10,5,0,0,0,0,8,0,0,0,0,4,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,6,12,0,0,0,10,7,0,5,0,6,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,6,0,4,0,0,0,0,0,7,0,0,0,0,0,0,0,4,9,6,0,0,0,7,0,0,0,0,0,0,0,0,8,6,0,0, +0,0,0,0,0,4,12,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,7,0, +0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,6,0,6,9,4,0,0,8,4,0,6, +0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,0,9,6,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,8,0,0,6,13,4,0,5,8,0,0,0,0,0,0,0,8,0,0,0,10,5,0,0,9,0,0,0,0,0,0,6,0,0, +24,0,0,0,0,0,0,0,8,0,0,7,0,0,12,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0, +6,8,0,10,0,9,7,0,0,0,5,0,0,0,0,0,0,0,4,8,5,0,0,0,0,8,7,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,19,0,0,4,0,0,0,0,0,6,0,0,0,0,0,5,0,0,0,0,8,0,0, +0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,10,4,0,0,0,0,0,0,0,6,0,0,0,4,20,0,0,7, +10,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,9,6,0,0,0,0,0,0,0,4, +12,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,9,4,0,5,0,0, +0,0,0,0,0,6,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,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,6,9,0,0,0,0,7,0,0,0,0,0,6,0,5,0,0,0,0,0,0,0,0,9,0,0,0, +0,6,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,17,7,0,0,13,6,14,6,0,0,0,0, +8,0,0,0,0,0,0,7,12,7,8,7,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,4,0,0,0,0,0,4,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,12,4,0,0,10,7,0,0,0, +0,0,0,10,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,12,0,0,6, +0,0,0,0,0,0,0,0,8,7,12,0,0,0,0,0,0,6,0,6,0,4,0,0,18,6,0,0,0,6,0,0,0,0,0,6,10,6, +0,0,0,0,0,0,8,7,14,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19, +0,0,0,8,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,8,7,0,0,10,5,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,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, +0,0,9,4,8,0,0,0,0,0,0,4,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0, +0,6,0,0,9,7,0,0,0,0,0,5,0,0,0,0,8,7,0,0,14,0,0,0,0,6,0,0,0,0,0,0,9,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,5,0,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0, +0,0,0,6,0,0,0,6,0,4,0,0,0,0,0,4,0,0,0,0,12,0,0,7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0, +0,12,0,16,6,0,0,0,0,0,0,11,7,0,4,8,7,0,0,0,0,0,6,0,0,0,0,16,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,10,7,0,0,0,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0, +0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,13,4,0,0,10,0,0,0,0,0,0,0,0,0,19,0,0,0, +0,0,0,0,0,0,0,0,0,0,8,6,22,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0, +5,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +4,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,18,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,14,7,0,0,11,5,0,0,0,5,0,0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,24,6,0,0, +0,7,0,4,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,7,0,4,0,0,0,0,8,7,0,0, +9,6,0,0,14,5,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,12,6,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,5,0,0, +0,0,12,7,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,6,0,0,13,7,0,0,0,0,0,0,14,0,11,4,0, +0,0,4,0,0,0,0,14,5,0,0,0,0,0,5,11,5,0,0,0,0,22,5,0,0,0,0,0,7,0,0,0,0,0,4,0,0,0, +4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,17,0,10,0,0,0,8,0,0,0,19, +5,18,7,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,10,6,0,6,0,0,0,0,10,4,0,4,0, +0,0,0,0,0,14,7,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,0,9,6,12,0,0,6,0,0,0,0,0,0,0,0, +12,0,10,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,5,13,0,9,7,0,0,0,0,0,0,0,0,0,0,0,7,9,7,0,0,8,0,0,0,0,0, +22,0,0,0,0,0,0,0,23,6,14,0,0,0,0,0,0,7,0,0,0,0,11,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0, +0,0,10,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,8,5,0,0,0,0,0,0,0,0,0,7,11,6,21,0,0,0,0,0, +0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0, +0,0,0,0,0,0,0,4,9,7,0,0,0,0,0,0,12,0,0,0,0,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,9, +0,0,0,20,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,11,7,0,0,0,0,0,0,0,6,15,0,0, +0,0,0,0,0,0,0,0,0,0,0,12,4,0,5,0,0,0,0,0,0,11,7,17,6,0,0,0,0,0,0,15,6,0,7,0,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,6,0,5, +0,0,11,0,11,7,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0, +17,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0,8,7,9,6,0,0,14,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0, +8,7,0,4,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0, +0,0,0,5,0,4,0,0,8,7,0,6,12,5,0,7,18,7,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0, +10,0,11,0,0,0,0,0,0,0,0,0,0,0,9,0,0,4,0,6,0,7,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0, +7,0,0,0,0,8,0,0,0,15,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,0,0, +0,0,6,0,0,0,0,23,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,5,0,0,0,0,0,0,8,6,0,0, +0,0,0,0,12,7,9,7,0,0,10,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,9,0,8,7,0,0,0, +6,0,6,0,4,0,5,0,0,0,0,0,5,8,7,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,7,10,5,0,0,11,6,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,4,9,7,0, +0,0,0,11,7,0,0,0,0,0,5,0,0,0,7,0,0,0,0,23,6,11,4,0,0,0,0,0,0,9,0,0,0,10,6,0,0,0, +0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,10,6,0,0,0,7,0,0, +0,0,0,0,0,0,0,0,20,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13, +6,11,7,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0,6,0,0,0,5,0,6,0,6,0,0,0,0,0,0,0,0,0,0, +0,6,0,0,0,0,8,7,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,4,10,0,8,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,10,6,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0, +0,0,0,0,0,0,10,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,11,6,0,4,0,0,14,5,0,7,0,0,0,0,0,6,16,0,0,0,0,0,0,0,10,0,0,7,15,0,0,0,11,7,0,0, +0,0,0,0,0,0,0,0,8,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,5,0,0,0, +0,8,0,0,6,0,0,0,0,0,0,9,5,0,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,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,16,6,0, +0,0,0,0,0,0,7,0,0,0,0,15,7,0,0,0,0,8,0,0,0,14,0,0,0,0,0,0,0,16,7,0,0,0,0,0,7,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,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,6,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,12,6,11,7, +9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13, +7,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,12,0,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,8,0,0,5,8,7,10,6,0,0,0,7,0,0,0,0,12,6, +0,0,9,0,0,0,12,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,10,0,0,0,10,5,0,0,0,0,0,0,9,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,6,0,0,9,5,0,4,0,0,0,6,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,5,0,0,0,0,0,0,0,0,9,0,0,5,0,0,8,7,8, +6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,10,0,9,4,0,0,0,0,0,0,0,6, +11,0,0,0,0,0,0,0,0,0,0,0,8,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,8,7,9,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,7,0,0,0, +0,0,0,10,0,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0, +0,0,8,4,0,5,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,22,0,0,0,0,0,0,0,8,5,0,0,0, +0,0,0,0,7,0,0,0,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,6,0,7,0,0,0,0, +20,0,0,0,0,0,0,0,0,0,0,7,9,0,0,0,0,0,0,6,0,6,0,7,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0, +0,0,0,14,7,0,0,0,5,0,0,22,4,10,0,0,0,0,0,0,4,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,11,5,13,0,0,0,0,0,0,0,0,0,8,0,0,7,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0,10,7,0, +0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,7,14,6,0,0,0,0,9,5, +0,0,0,0,0,6,0,0,0,5,10,0,8,6,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,8,4,0,6,0, +0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7, +14,0,0,5,0,0,18,0,8,4,0,6,0,0,20,0,13,0,0,0,0,7,0,4,0,0,0,0,0,4,8,4,0,0,0,0,0,6, +0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,0,14,0,0,0,0,0,9,7,0,0,9,0,0,0,0, +0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,20,0,14,0,0,4,0,6,8,5,0,0,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,10,4,12,7,0,6,0,0,9,7,10,5, +0,0,8,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,0,18,0,0,0,14,7,0,0,0,0,0,4, +0,0,0,0,0,0,17,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0, +0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,8,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,7,0,0,0,0,0, +7,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,5,0, +0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,23,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,0,0,4,0,0,0,0,0,0,12,7,8,4,0,0,0,0,0,0,0,0,0,6,0,0,9,5,0,0,0,7,0,0,0, +0,0,0,0,0,0,4,10,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,0,0,18,7, +0,0,8,0,0,5,0,0,10,0,0,0,0,0,0,6,0,0,0,0,0,5,0,7,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0, +6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,6,0,0,10,0,0,5,10,4,0,0,12,0,0,0,0, +6,22,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,7,0,5,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,6,0,7,0,0,0,6,0,6,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0, +0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,16,6,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,12,7,0,0,0,0,9,0,0,0,0,6,0,0,11,0,0,0,0,0,13,0,9,6,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,10,7,0,0,0,7,0,6,0, +0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,11,0,15,0,22,7,0,4,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0, +18,0,0,0,0,0,0,0,0,0,14,0,0,4,0,0,0,0,8,7,9,0,0,0,0,0,9,0,0,0,14,0,0,0,0,0,0,0, +0,0,11,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,7,0,0,0,6,0,6,0,0,0,0,8,0,0,0,0, +0,11,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,9,4,0,0,0,0,0,4,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,6,8,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0, +0,0,0,0,0,0,8,6,0,0,9,5,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,5,0, +0,10,6,9,0,0,0,0,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0, +11,7,12,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,4,0,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0, +0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,5,0,0,10,6, +0,0,0,4,0,7,13,0,0,4,0,0,11,4,0,6,0,0,0,0,0,6,8,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,5,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,5,0,0,0,0,12,6,0,0,0,0, +11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,11,5,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8, +7,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,6,17,0,9,0,10,6,0,6,12,0,0,4,0,0,0, +0,0,0,0,0,0,0,8,5,12,7,0,4,0,0,0,0,0,0,0,0,0,0,11,0,9,0,10,6,11,5,0,7,0,0,8,0,0, +7,0,4,0,0,0,7,0,0,0,0,0,0,8,6,0,0,0,6,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,11,0,0,0,0,6,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,10,0,0,0,0,0,8,6,0,0,0,0,0,6,12,0,0,0,0,0, +0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,6,0,0,16,0,11,5,0,0,0,0,0, +0,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,9,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,6,10, +7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,0,9,5,0,0,0,0,8,0,9,0,0, +0,0,0,0,0,0,7,10,0,13,0,0,6,0,0,0,0,0,0,0,0,0,6,9,4,0,0,0,0,0,0,10,0,0,0,0,0,10, +0,0,0,0,0,0,0,10,6,11,0,0,0,0,0,9,0,0,0,0,0,0,4,0,0,0,0,0,0,10,5,0,0,0,0,0,6,0, +0,0,0,0,0,18,4,0,7,0,0,0,0,0,0,24,0,8,6,0,7,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,5,0,0,0,0,10,7,0,6,0,0,0,0,0,0,0,0,8,5,10,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0, +6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,4,0,5,15,0,0,0,0,7,0,7,0,0,0,0, +0,0,0,0,0,6,10,5,0,0,0,6,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,12,0,0,0,0,0,0,0,0, +0,0,5,0,0,0,0,0,0,14,4,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,11,0,10,4,9,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,7,0,0,0, +0,0,0,0,0,0,0,0,7,13,7,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,8,0,10,6,0,4,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0, +0,0,0,0,0,0,0,10,6,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,5, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,9,7,0,0,0,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,0,6,0,0,0, +0,0,0,0,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,6,0,0,0,5,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,8,6,11,0,0,0,0,6,0,0,0,0,0,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,0,0, +6,0,0,0,0,0,0,0,6,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0, +0,0,0,0,0,0,0,6,0,6,0,0,0,5,0,0,0,0,0,0,0,5,0,0,10,0,11,5,0,0,0,0,0,0,14,7,9,7, +0,6,0,0,0,0,0,4,0,0,0,0,0,0,11,7,0,6,0,0,0,0,0,0,9,7,0,4,0,0,0,7,0,0,0,0,0,5,0, +0,0,0,0,5,0,0,0,7,0,0,0,0,0,5,0,0,0,0,17,5,0,0,8,0,0,0,0,6,9,4,0,0,0,0,0,0,0,0, +8,7,11,7,9,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,6,9,5,0,0,8,6,0,0,0,5,0, +0,0,0,9,0,0,0,9,6,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0, +0,0,0,0,4,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,4,0,0,0,5,0,0,0,0,0,7,0,0,0,0,0,7,13,5,0,0,0,7,0,0,0,0,0,7,9,6,11,7,0,7,0,0,0, +0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,8,5,0,0,0,5,9,4,0,0,0,0,0,0,0,0,8,4,0,0,0,0, +24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0, +0,0,0,0,6,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,5,11,6,0,4,0,7,20,0,8,5,9,5,9,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,7,23,5,0,0,8,4,0,0,10,0,0,6,0,5,0,0,0,0,0,0,0,0,0,0,0,7,0, +0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,0,0,0, +10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0, +6,0,0,0,0,14,0,18,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,6,0,4,0,0,0,0,0,0,8,4, +11,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0,12,0,10,7,0,0,10,0,0,0,0, +0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,6,0,0,0,0,8, +6,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,4,0,6,0,4,0,0,0,0,0,5,0,0, +0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,4,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,17,7,11,0,0,0,0,0,0,0,0,0,0,4,12,6,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0, +0,5,12,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,6,0,0,20,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,4, +0,0,0,5,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,6,0,4,13,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,12,6,0,7,0,0,0,0,10,0,23,6,0,0, +0,4,0,0,0,0,0,6,8,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, +10,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,11,0,9,7,0,0, +0,0,0,0,0,0,0,0,9,7,0,4,0,0,0,0,8,7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, +0,0,0,0,0,6,0,0,10,7,10,5,0,0,8,0,8,0,0,0,0,0,0,4,0,5,10,0,0,0,0,0,0,0,9,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,11,7,0,0,0,0,0,0,0,0,9,4,0,0,0,0,0,6,0,0,8, +7,0,0,0,0,0,5,0,0,0,0,0,0,0,0,10,0,0,0,0,5,0,4,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,24,7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,6,0,0,9,0,0,0,0,0,0,7,0,6,13,0,8, +0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,6,0,0,0,0,8,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0, +4,0,0,0,0,0,4,0,0,0,0,0,0,0,6,8,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,4,0,4,0,0,0,5,0,7,0,0,10,0,10,7,0,0,12,5,0,0,9,0,0,0,10,0, +0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0, +12,0,0,0,0,0,8,5,13,6,0,0,0,0,0,0,9,4,0,0,0,0,8,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0, +0,0,6,0,0,14,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,17,6,0,0,0,0,12,6,0,0,0,0,8,0,0,7,0, +7,0,4,9,0,0,6,0,0,0,6,0,0,0,0,0,0,8,7,0,0,0,0,0,0,11,0,0,4,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,18,7,0,4,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,0,0, +0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,8,0,11,7,0,0,0,0,0,0,0,0,0,4,0,0,0,0, +11,0,0,0,0,0,0,0,21,0,0,6,10,0,0,0,0,0,9,0,10,0,0,0,0,0,11,0,0,0,0,6,0,0,0,0,0, +5,0,0,0,0,0,0,10,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,4,0,0,23,7,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,7,0,0,0,0,0,0,0,0,9,7,0,0,0,7, +0,4,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,4,0,6,0,0, +11,6,0,0,0,0,0,0,0,6,0,0,0,0,10,7,0,0,9,4,0,0,11,0,8,5,0,0,0,7,8,5,22,0,0,0,9,6, +0,0,0,0,0,0,0,6,10,4,0,0,0,0,0,7,9,4,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0, +0,0,0,11,6,0,0,0,0,0,0,0,0,0,0,0,7,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0,6,0,6,0,4,0,0, +0,0,0,0,0,7,0,7,0,4,13,0,0,0,0,0,8,0,0,0,0,7,0,0,0,0,0,0,11,6,0,7,0,0,0,0,9,0,0, +0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,10,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,4,8,0,0,0,0,0,8,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,6,0,0,0,0,13,5,8,0,0, +0,0,0,0,0,14,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,17,6,0,0,0,0,13,4,0,0,9,6,0,0,10,5,0, +0,10,5,0,0,0,0,13,0,0,0,0,6,0,0,0,0,0,0,10,0,12,0,0,0,0,0,0,0,0,0,0,0,8,4,0,4,0, +0,0,4,0,0,0,0,0,4,0,0,12,0,0,5,9,4,0,0,0,0,0,0,0,0,0,5,8,5,0,0,0,7,0,0,0,0,8,7, +0,0,0,6,12,5,0,0,0,5,0,0,0,5,0,0,0,0,0,4,12,0,0,0,9,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,4,8,7,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0, +0,9,6,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,4,11,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,12,7,0,0,0,7,10,7,0,0,11,0,0,0,0,0,0,0,0,0,11,7,0,0,0,6,0,0,11,0,0,0,0, +0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,22,0,10,7,0,0,8,5,0,0,0,0,0,5,0,0,0,0,0,0, +0,0,0,0,9,6,8,7,0,6,0,0,0,0,0,5,0,0,0,0,0,0,8,7,0,0,0,0,9,7,0,0,0,6,0,0,8,7,0,0, +0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,5,0,0,0,4,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,18,6,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9, +6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,5,0,0,0,0,14,0,0,0, +9,0,0,0,0,0,0,0,0,0,9,7,12,7,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,12,0,0,0,0,0,12,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,10,7,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,6,0,0,0,0,0,0,9,6,0,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,9,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,6,0,7,12,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0, +0,7,0,0,8,6,0,0,0,0,10,7,0,0,0,0,0,0,0,6,0,0,0,0,0,6,12,0,0,0,0,0,0,0,0,6,0,0,0, +0,0,6,0,0,0,6,0,0,0,0,0,6,16,0,0,0,0,0,0,0,0,0,9,0,17,0,14,7,8,0,0,0,0,0,0,6,0, +0,0,0,0,0,0,0,0,0,11,0,0,6,8,7,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0, +9,0,0,0,0,7,0,0,0,0,11,5,0,4,9,6,8,0,0,0,0,0,0,0,0,0,10,0,11,7,0,0,0,0,0,0,0,0, +9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11, +0,0,0,12,0,0,0,0,0,10,5,0,4,0,0,0,0,0,7,10,6,11,6,0,0,0,0,0,0,0,0,0,0,0,0,17,0, +0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,8,0,0,4,0,0,0,6,0,0,0, +0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,4,0,0,0,0,9,6,0,0,0,4,0,0,0,0,0,4,10,7,0,7,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0, +0,0,0,0,0,0,6,0,0,0,6,0,6,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,18,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,13,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4, +0,0,0,6,0,0,0,0,0,4,8,0,0,0,11,7,0,0,0,4,0,0,0,0,0,7,0,0,8,5,0,0,16,0,0,0,13,6, +0,0,0,0,0,0,0,6,0,0,0,0,20,0,11,6,0,0,8,7,0,0,0,0,0,6,17,0,8,0,0,0,0,0,8,7,0,0, +9,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0, +0,0,4,0,7,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,8, +0,8,0,0,0,0,0,0,0,11,0,8,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,6,0,0,9,0, +0,0,0,0,8,0,0,0,0,0,18,0,0,0,0,0,0,4,9,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,9,6,0,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,7,0,0,0,0,0,0,0,0, +0,4,0,0,0,0,0,0,14,0,0,0,0,7,0,6,0,0,8,0,20,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,8,0,0,0,14,0,0,0,0,0,0,0,8,0,0,7,0,6,0,0,0,7,0,0,0,0,0,0,0,0, +0,0,0,4,12,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,10,6,0, +5,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0, +0,0,0,5,8,4,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,12,7,0, +0,0,0,13,6,0,0,0,7,0,0,8,0,0,0,8,0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,0,0,0,0,0,0,11,5, +0,6,0,0,8,5,0,7,0,0,0,0,0,0,0,7,0,0,0,0,8,6,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,4,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,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +14,0,10,7,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,19,0,0,4,0,0,0,7, +0,0,11,5,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,16,0,10,5,18,0,0,7,9,6,0,5,0,0,0,0,0, +0,0,0,0,5,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,5,0,0,0,7,0,6,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,4,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,23,0,0,0,0,5,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,14,0,20,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0, +11,0,0,0,0,7,0,0,0,0,15,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,7,0,0,0,0, +0,4,0,0,0,0,10,0,0,0,0,0,9,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,10,0,11,6,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,5,0,0,11,0,0,0,0,7,0,0,0,0,0,0,8,7,0, +4,0,0,0,0,11,0,0,0,0,0,11,0,0,5,0,0,8,7,0,4,0,7,0,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,10,5,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,6,0,5,0,0,0,0,0,0,0, +0,0,4,11,5,10,7,0,7,0,0,9,6,9,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,9,4,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,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,8,6,0,0,0,0,11,7,0,0,0,0,0,0,0,0,0,0,11,7,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,8,5,0,0,8,0,9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0, +10,7,0,0,0,6,0,0,0,0,0,0,8,0,0,6,0,0,0,6,10,0,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,6,0, +0,0,6,0,0,0,0,9,5,8,5,8,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0, +0,8,7,10,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,0,5,0,0,0,6,0,7,0,0, +10,5,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,11,0,0,0,0,0,13,4, +0,0,0,4,0,0,0,0,0,5,8,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,7,14,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,6,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,4,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,7,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,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,4,0,5,0,0,15,6,10,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,14,6,10,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,6,0,5,11,4,0,6,0,0,0,7,0,0,0,0, +0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,5,0,0,8,5,0,0,0,0,0,0,0,0,0,0, +0,0,10,0,0,0,0,0,9,6,9,4,0,0,0,4,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,5,0, +0,0,0,0,0,0,0,0,0,0,4,0,0,11,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0, +0,0,0,7,12,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0, +4,9,6,0,4,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,6,0, +7,8,6,0,0,0,0,0,0,0,4,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,5,0,4,0,0,0,0,0,0,0,5,0,0,0, +0,0,5,0,0,0,7,12,7,0,0,0,0,0,0,18,4,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,6,0,0,0, +0,12,0,0,7,0,0,0,0,0,7,0,0,13,0,0,6,0,0,0,0,8,7,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,7,10,5,0,0,8,0,0,0,0,0,0,0,8,6,0,7,0,0,8,4,0,4,0,0,0,0,10,4,0,0,14,0, +0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,17,0,0,0,0,0,0,6,0,0,0,0,8,6,0,0,10,5,0,0,0,0,8, +6,0,0,0,6,0,0,0,7,0,0,0,0,0,6,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,12,0,0,0,0,6, +8,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,7,0,0, +0,0,0,6,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,4,24,0,0, +0,0,0,12,6,0,0,10,6,0,5,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,17,7,0,5,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,11,5,9,0,8,7,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,10,7,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,5,8,7,0,0,0, +0,8,5,0,0,0,0,10,7,0,7,0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0, +0,6,12,0,8,7,0,0,0,0,0,0,0,0,0,0,16,0,10,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,22,0,0,0, +0,0,0,0,0,0,0,0,0,0,13,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,22,0,0,6,0,0,21,0,0,0,22,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,7,8,0,0,0,0,6,14,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,6,0,0,8,6,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,0,8,5,0,0,11,7,0,6,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,5,0,0,0,0,0,0,0,0,0,4,0,0,8,7,0,0,0,0,8,5,11,7,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,8,5,0,0,10,0,0,4,13,7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,0,13,6, +0,6,0,7,0,0,8,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,15,0,0,0,10,7,0,0,0,0,0, +7,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,19,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,6,0,5, +0,7,0,0,0,0,0,0,0,0,0,6,0,0,11,4,0,0,0,6,0,0,13,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,12,6,0,0,0,0, +0,7,0,0,0,0,0,0,11,7,0,0,0,0,0,6,0,0,10,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,11,6, +0,0,0,0,0,0,0,0,10,0,0,0,0,6,0,0,0,0,0,0,8,7,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,0,0, +0,0,0,8,7,0,0,0,0,9,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,10,0, +0,6,0,0,13,0,0,0,0,0,0,0,9,6,0,0,8,6,8,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0, +0,9,7,0,0,0,0,0,0,11,0,0,0,10,7,0,0,0,0,0,0,0,0,9,6,0,0,12,4,0,4,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,21,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,5,0,0, +9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0, +16,0,0,4,0,0,0,0,0,7,0,0,0,6,0,6,0,0,11,0,0,0,0,5,0,0,0,0,0,0,0,4,8,5,0,0,0,0,0, +0,14,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0, +0,0,8,0,0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0, +0,0,0,0,6,9,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,14,7,0,0,9,7,0,0,11,0,0,0,0,0,10, +4,11,5,13,6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,5,0,0,0,0,0,4,0,0,9,0,0,0,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,6,12,5,0,0,0,6,14,0,0,0,0,0,0,0,0,0,0,4,9,4, +0,0,0,0,0,5,0,0,0,0,0,0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0, +0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,11,6,0,0,13,7,0,0,13,6,0,7,0,0,0,0,0,0,8,6,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,10,6,0,4,0,0,12,6,0,0,0,0,0,0,0,0,10,6, +0,0,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,7,0,0,9,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,6,0,0,8,6,0, +0,0,7,11,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,8,0,0,0, +0,0,0,5,12,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,12,0,0, +0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,8,7,0,0,8,5,0,0,0,4,9,5,0,0,0,7,10,6,0,0, +0,0,0,0,9,7,0,0,8,5,8,0,8,4,0,0,13,0,0,0,0,0,0,0,0,0,0,0,0,5,0,5,0,0,0,0,0,0,0, +0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,4,0,0,0,0,0,0,0,0,0, +0,11,7,0,0,0,7,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17,5,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9,7,0,0,0,0,8,5,0,4,0,0,0,0,0,6,0,6,14, +6,0,0,0,0,9,6,0,0,0,0,0,0,8,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,6,0,0,0,0,14,7,9,7,8,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,6,16, +0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,14,0, +0,6,0,0,8,6,0,0,0,0,0,6,0,0,12,0,0,0,0,0,8,5,0,7,11,0,0,5,0,4,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,9,6,0,4,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,10,5,0,0,0,0, +0,4,0,0,0,7,11,6,0,4,8,5,9,5,0,0,0,5,0,7,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,5,14,7,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,16,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,9,6,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,9,0,0,0,12,5,0,0,0,0,0,0,0,4,10,5,0,0,0,0,0,0,0,0,0,0,0,6,0, +0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,4,0,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,10,4,0,0,0,0,0,5,0,0,0,4, +0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,0,10,7,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,7,10,7,0,0,0,0,0,0,0,0,15,0,0,0, +0,0,0,0,0,0,0,7,0,0,0,0,0,7,10,7,9,7,0,0,0,7,0,0,8,0,0,0,0,0,0,0,9,0,0,0,8,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,8,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,7,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,15,7,12,6,0,0,0,7,0,5,0,0,0,0,0,0,0,0,0,0,0,0,18,0,0,5,0,0,0,0, +0,0,0,6,9,5,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,9,7,0,0,14,0,0,0,11,7,0,0,0,0,0, +0,0,0,0,0,0,4,0,0,11,7,0,0,0,0,8,0,0,0,0,0,0,6,8,7,0,0,0,7,10,4,0,0,0,0,0,0,0,0, +0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,10,0,0,0,0,0,0, +6,0,6,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,11,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,7,0,0,10,7,0,0,0,0,9,7,0,0,0,0,0,0,13,7,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,12,0, +0,0,0,6,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,7,0,0,9,6,0,0,11,0,0, +0,0,0,14,4,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,23,7,0,0, +0,0,0,6,0,7,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,20, +7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,0,0,0,0,0,0,0,0,0,11,5,0,0,0,0,0,0,0,0,0,0,10,4,0,0,0,5,8,5,10,4,0,0,0,0,0, +0,13,6,9,7,0,0,10,7,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,6,0,0,0,7,0,6,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,7,10,7,0,0, +0,0,0,0,0,0,0,0,12,4,0,0,0,0,8,7,0,0,0,0,0,7,0,6,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0, +0,0,0,0,6,0,6,9,6,0,0,12,5,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0, +0,0,0,0,0,0,0,0,0,5,8,7,9,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,11, +4,0,0,0,0,0,0,8,0,0,0,10,7,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,0, +0,0,0,0,0,5,0,6,0,0,10,0,14,0,0,0,0,0,0,0,23,0,0,0,12,0,10,5,0,0,0,0,0,0,0,0,0, +5,0,0,0,0,8,0,0,0,0,6,8,0,0,0,0,0,0,0,0,0,22,0,8,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0, +0,0,0,0,0,6,18,4,0,0,0,7,10,6,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0, +0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,7,10,0,0,0,0,0,0,6,0,0,0,0,11,5,0,0,0,0,0,0,0,0, +15,0,8,6,0,0,13,7,0,0,0,0,0,7,0,0,0,0,0,7,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,9,5,9, +0,0,6,8,6,0,0,0,0,10,0,0,0,18,5,0,0,0,5,0,7,0,0,0,0,8,6,0,0,0,0,9,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,14,0,23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,6,0,0,0,5,0, +0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,8,5,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,0,0,0,0,0,0, +0,0,0,0,20,5,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,9,5,0,0,0,0,0,0,8,4,24,0,0,0,0,0,0, +0,0,0,0,0,0,0,9,7,0,0,0,0,10,5,0,0,8,5,0,0,0,0,0,0,0,0,12,7,0,6,0,0,10,6,0,0,0, +0,14,0,0,4,9,5,0,0,0,0,0,0,9,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,8,0,0,0,0,0,11,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,8,5,11,7,0,4,0,0,10,0,0,0,0, +0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,11,6,0,0,0,0,0,5,14,6,0,0,0,0,10,0,0, +0,13,4,0,0,0,0,0,0,0,0,0,0,0,6,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,7,12,0,10,6,0,0,0,0,0,0,10,0,0,0,0,0,10,0,9, +7,0,0,0,0,0,0,0,0,0,0,0,0,0,7,8,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,9,7,0,0,0, +0,0,0,0,0,0,0,0,0,24,0,11,7,0,7,0,0,0,0,0,0,8,6,0,0,0,0,0,0,8,7,0,0,0,0,0,5,0,0, +0,6,9,0,0,0,23,5,0,0,0,0,0,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16,7,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,0,0,18,4,0,0,11,7,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,9,0,0,0,11,0,0,0,23,0,0, +0,10,4,0,0,0,0,0,7,0,0,0,7,0,0,0,0,0,4,0,0,0,0,0,7,0,0,19,0,11,0,0,0,0,0,12,7,0, +0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,0,0,0,6,0,0, +9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,4,0,0,0,0,10,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,22,0,8,7,10,4,11,0,13,5,8,7,9,0,8,7,0,0,0,7,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0, +0,8,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,4,0,0,0,4,11,0,0,6,0,0,8,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,5,0,0, +20,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,7,0,0,14,0,0,0,9,0,13,7,0,0,0,0,0,6,0,7,0,0,8,6,10,6,0,0,8,6,0,0,0,6,0, +0,12,6,9,0,0,0,0,0,0,5,9,0,12,4,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0, +0,0,4,8,0,0,6,8,0,0,0,0,0,0,0,0,0,13,6,0,7,0,0,0,0,0,6,8,7,8,6,0,0,0,7,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,18,0,11,4,0,0,0,5,0,0,0,0,0,0,0,0,0,0, +0,5,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,4,14, +6,0,0,0,0,12,7,8,0,0,0,0,0,0,0,8,7,0,0,0,0,10,4,0,0,0,0,0,0,10,0,0,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,15,6,9,7,0,0,0,0,0,0,15,6,11,7,0,0,0,7,0,0,21,0,0, +0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,17,6,0,0,10,5,0,5,0,0,0,0,0,0,0,0,0,7, +0,0,10,0,0,0,0,0,0,0,0,4,11,5,0,0,0,0,16,7,0,0,0,0,0,6,0,0,8,7,0,4,0,0,10,0,0,0, +0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,0,0,0,0,0,0,6,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,8,0,0,0,0, +0,0,0,10,4,0,0,0,0,0,0,0,0,0,6,0,5,0,0,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0, +0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,6,10,7,0,0,0,0,0,0,0,0,8,4,0,0,10,0,0,0,0,4,0,6,0,6,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,7,0,0,0,7,17,0,0,0,0,0, +0,0,0,0,0,0,10,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +6,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,4,0,0,0,0,0,6,0,0,0,0,0,0,10,5,0,0, +0,5,0,0,0,0,9,0,19,7,0,0,0,0,0,7,0,0,0,0,10,6,0,0,0,6,0,5,0,0,0,0,0,0,0,0,0,6,8, +0,0,0,0,0,11,0,0,0,0,0,0,6,0,0,0,0,0,7,9,0,15,0,0,0,0,0,0,0,0,0,0,4,0,0,0,5,0,0, +0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0,9,0,0,0,0,0,0,0,0,6,0,7,0,0,0,0,0,0,0,6,0,0, +0,0,0,6,10,0,0,0,0,0,0,0,23,0,14,0,0,0,0,7,0,0,0,0,0,7,0,0,9,0,0,0,0,7,0,0,0,0, +0,6,0,0,14,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,6,0,0,0,4,0,0,0, +0,0,0,0,0,9,5,0,0,0,0,0,4,0,0,0,0,9,5,0,0,0,0,22,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,22,0,0,0,0,0,0,0,10,0,0,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,6,11,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,14,7,0,0,12,7,0,0,0, +0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,8,6,10,0,0,0,0,0,0,0,0,0,10,7,8,5,0,0,0,0,0,0, +0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,5,0,0,9,5,0,0,0,0,0,5,0,0,0,0,0,4,0,0,0, +0,0,0,0,0,0,0,12,4,11,0,0,0,9,0,11,7,0,0,0,0,0,0,10,6,0,0,0,6,0,0,0,0,15,5,0,0, +11,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,4,0,4,0,6,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,8,0,0,0,19,7,0,4,0,0,9,0,0,0,0,0,10,0, +0,6,0,0,13,0,12,6,0,0,0,0,0,0,0,0,10,7,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,13,7,10,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,6,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,4,9,0,0,0,10,0,0,0,0,0,0,0, +0,5,0,0,0,0,0,0,10,0,23,6,0,0,0,6,8,0,0,0,0,0,0,0,0,0,17,7,0,0,0,0,11,6,22,5,0, +0,9,6,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,5,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,4,11,0,9,4,0,0, +0,7,0,7,0,0,0,0,0,0,12,4,0,0,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +4,0,0,11,5,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,8,6,0,0,0,4,0,0,0,0, +0,0,0,0,0,7,0,0,0,4,0,0,10,4,0,0,0,0,0,0,0,7,0,7,0,0,0,6,0,0,0,0,8,6,0,6,0,6,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,0,0,0,0,9,5,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,6,22,6,12,0,0,6,0,0,0,6,0,0,0,0,0,7,0,0,0,0,11,0,0,0, +9,7,0,0,0,0,0,4,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,6,0,0,0,6,0,6,0,0,8,7,0,0,0,4,9,7,19,0,0,0,0,0,0,0,0,0,9,6,10,6,0,6,0,0,0, +4,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,6,16,7,10,6,0,0,23,6,11,7,0,4,0,0,0,0,0,0,0,0,0, +5,0,0,0,0,10,7,0,0,0,0,0,7,0,0,0,0,0,0,15,0,10,0,0,0,14,6,0,0,0,0,0,0,0,0,0,0,0, +5,0,0,0,0,0,0,0,5,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,5,0,0,11,5,0,0,0,0,0,0,0,0,0,0, +0,4,0,0,0,0,0,6,0,0,10,0,0,0,0,7,0,0,0,0,0,0,10,6,0,0,0,0,8,4,0,0,0,7,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,7,12,5,0,0,0,0, +0,6,0,0,0,0,9,6,0,0,0,0,0,0,0,6,9,0,0,0,0,6,0,0,0,0,8,7,0,0,0,0,0,0,0,6,0,0,0,0, +0,0,0,0,0,0,10,5,0,0,0,0,0,0,8,6,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,8,5,0,0,0,0,0,7,0,7,0,4,0,0,10,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,5,0,0,0,0,13, +7,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,7,0,0,13,0,0,0,0,0,0,0,0,7,10,5,0,0,0,0,0,0,9,7,0,0,8,6,9, +5,0,0,0,0,0,6,12,0,0,0,0,0,0,0,18,6,0,0,0,0,0,0,0,0,19,7,0,4,0,0,0,0,9,5,0,5,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,7,0,0,0,0,0,0,14,0,0,0,23,7,8,7,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,22,0,0,7,0,0,0,0,0,0,0,0,9,7,8,4,0, +0,0,0,0,0,0,0,8,5,0,6,0,0,0,0,0,6,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0, +8,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,12,5,0,0,0,0,0,0,0,0,0,0,8,6,0,0,11,7,0,0,0, +0,12,0,8,6,19,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,11,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,11,7,0,0,0,0,0,4,10,0,0,0,0,0,0,0,8,7,0,0,0,0,14,0,8,0,0,6,10,0,0, +0,0,0,0,0,12,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,6,0,0,0,0, +0,0,0,0,13,0,0,0,0,0,0,0,11,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0, +0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,5,0,0,0,6,0,0,0,5,0,7,0,0,0, +0,0,6,0,0,21,7,0,0,9,6,0,0,0,6,0,0,13,7,0,0,0,5,0,0,0,0,0,4,0,6,0,0,0,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,0,11,5,0,6,0,0,10,5,0,0,0,0,0,0,0,0,9,6,0,0,8,7,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,0,0,0,0,0,0,6,0,0,0,0,15,4,0,0,12,7,0,0,0,6, +0,7,0,0,8,0,9,5,0,4,0,0,0,6,0,6,0,0,23,4,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,4,0,0,8, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0,0,0,0,0,0, +7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,12,6,0,0,0,0,0,0,10,7,0,7,0,0,0,0,0,0,0,0,0,0, +9,0,0,0,0,0,8,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,11,5,0,0,0,6,0,6,0,0,0,0,0,0,0,6,0, +4,0,0,0,0,0,0,0,0,0,0,0,5,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,8,7,0,0,0,6,0,6,0, +0,0,0,0,0,0,0,0,5,0,0,0,0,0,5,0,0,0,0,11,0,0,0,0,0,0,0,10,5,9,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,8,0,23,7,0,0,0,0,0,7,0,0,10,6,18,0,0,0, +0,0,0,0,8,7,0,6,0,0,0,0,0,0,8,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0, +0,0,0,0,0,6,0,0,0,4,12,7,0,0,0,0,0,0,0,0,10,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,13,5,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0, +11,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0, +0,0,0,0,6,0,0,0,4,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,0,11,0,0,0,0,0,0,0,0,0, +17,5,0,4,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0,0,0,0,8,7,0,0,0,0,0,0,0, +0,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0, +10,0,0,0,8,6,0,0,0,7,0,0,0,0,0,0,8,0,0,0,14,0,0,0,0,7,0,0,0,4,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,9,4,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0, +10,0,0,0,16,5,0,0,0,0,0,0,8,0,0,4,0,0,0,0,0,0,0,0,0,0,9,6,0,0,0,0,0,0,10,0,0,0, +0,0,0,0,0,5,0,0,0,0,12,5,0,7,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,7,0, +0,0,0,0,0,0,0,12,6,0,0,0,0,0,7,0,6,0,6,12,6,0,0,0,0,0,0,0,4,8,7,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,20,0,0,0,0,6,0,6,0,0,0,0,0,0,0,0,10,6,8,0,0, +6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +16,0,8,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,23,5,0,0,0,7,0,6,0, +0,0,0,0,0,0,0,0,0,0,0,10,6,0,0,9,5,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,10,0,0,0,14,0,0,0,0,7,0,0,0,4,17,5,0,0,0,0,11,0,9,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,6,0,0,0,5,0,7,0,0,0,0,0,0,0,0,8,0,0,0, +12,6,0,0,0,0,0,0,13,0,0,0,0,7,9,0,0,0,0,0,0,0,0,0,0,5,0,0,0,7,10,7,12,0,0,0,9,0, +0,0,14,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,15,6,0,0,23,0,0,7,0,6,0,0,0,7,0,6, +0,0,0,0,0,0,0,6,0,6,9,0,0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,8,7,9,4,0,0,10,0,0,0,10, +6,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,23,0,0,6,0,0,0,0,0,0,9,4, +0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,9,6,0,0,0,0,8,6,0,0,0,0,0,0,0,0,12,0,0, +0,0,0,8,0,0,6,11,6,0,0,8,7,8,5,0,0,0,0,0,5,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,0, +10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0, +7,0,0,0,0,9,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,8,0,0,0,0,6,12,5,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,10,0,10, +7,0,0,8,0,0,0,0,4,0,0,0,6,0,0,0,6,0,0,0,6,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0, +0,0,4,0,0,0,0,0,4,0,0,0,0,0,0,0,6,0,6,0,5,0,0,0,0,8,0,0,0,10,7,0,0,0,0,10,0,0,0, +0,0,13,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,19,7,0,4,12,0,8,0,0,0,0,6,0,0,0,0, +0,0,0,6,0,0,0,0,0,0,0,0,0,4,0,0,0,0,18,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0, +0,14,0,0,4,0,0,0,6,0,0,0,6,0,0,0,7,0,0,0,0,0,0,10,4,0,0,9,7,0,0,11,0,0,0,0,0,0, +7,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,12,0,0,0, +0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,22,5,9,7,0,0,0,0,0,0,0,0,0, +0,0,6,0,0,9,6,0,5,0,0,0,0,0,0,10,5,0,0,8,6,0,6,10,5,0,0,0,6,0,0,0,6,0,0,20,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,9,0,0,0,0,6,0,0,0,0,17,4,0,7,0,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10, +0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0, +0,0,7,0,0,8,6,12,0,0,7,18,7,0,0,8,4,0,0,0,0,9,6,0,0,0,0,0,0,0,0,13,0,0,6,0,0,0, +0,0,0,0,0,0,0,10,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,0, +0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,8,5,0,0,0,0,0,0,0,0,12,0,0,0,8,0,0,0,0,0,0, +4,0,0,10,0,16,0,0,0,0,0,0,0,12,7,10,7,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,6,16,6,10,0,0,5,0,0,0,0,0,6,0,0,0,0, +0,7,0,0,0,7,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,5,8,7,0,7,0,0,0,0,0,0,0,0,8,0,0,6,0,0,0,6,0,0,0,4,0,0,0,0, +8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,7,0,0,8,0,0,0, +9,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,13,5,0,5,0,0,0,7,8,4,0,0,0,0,0,0,0, +0,12,0,0,0,0,0,0,0,0,0,0,0,8,6,0,6,0,0,11,0,0,0,0,0,0,0,0,6,0,0,0,0,0,4,0,0,0,0, +0,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,10,7,0,4,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,9,0,11,6,0,0,10,6,0,0, +0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,6,0,0,0,7,0,0,9,0,8,7,11,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,9,6,10,5,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,10,7,0,0,0,0,0,0,11,0,9,6,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,5,0,6,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,15,5,12,5, +0,0,0,0,0,0,12,7,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,12,6,0, +0,0,0,24,4,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,4,10,4,0,0,0,0,10,7,0,0,0,0,0,0,0,0,0,0,0,0,9,0,11,0,0,0,0,0,0,0,0,0,0,6, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5, +0,0,8,0,0,0,0,7,0,0,0,0,0,0,10,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,0,0, +0,0,0,0,0,14,7,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,0,0,6,0,0,0,0,0,6,0,0,0,6,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,0,0,7,20,7,11,4,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19,7,9,6,0,0,12,7,0,0,0,0,0,0,10,0,12,0, +0,0,0,0,0,4,9,6,13,0,0,0,0,0,0,0,0,6,0,0,0,6,0,0,0,5,0,0,0,0,0,0,8,0,0,0,0,0,0, +0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,6,0,0,11,0,9,0,0,0,0,4,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,8,5,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, +0,4,0,5,0,0,0,0,0,0,0,0,0,4,0,0,0,0,9,7,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, +0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6, +0,0,0,0,8,7,0,0,0,0,0,0,12,0,0,6,0,0,0,0,0,0,0,6,8,4,0,0,10,7,0,0,10,0,0,0,0,0, +0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,7,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,4,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,7,0,0,0,0,0,0,0,5, +0,4,0,0,0,0,0,6,0,0,0,0,0,0,8,0,0,6,0,0,0,6,0,0,0,0,0,7,0,5,8,4,0,0,9,0,0,0,0,4, +0,0,0,0,0,0,0,0,0,5,0,0,15,6,8,6,0,0,0,6,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,6,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,9,6,0,0,0,0,0,0,0,7,0,0,0,4,0, +6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,9,5,0,6,12,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,8,7,0,6,0,0,0,0,0,0,0,0,0,0,0,0,11,0,12,7,0,0,0,0, +0,0,0,0,0,5,0,5,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,11,4,0,0,0,0,0,0,0,0,0,0,10, +7,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,7,8,7,9,6,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,5,12,0, +10,5,12,6,0,0,0,7,0,0,0,0,0,0,0,5,0,0,0,5,9,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7, +11,7,0,0,0,0,0,0,0,0,0,0,17,0,0,0,0,0,0,6,0,7,0,0,0,0,8,0,8,5,0,6,0,0,0,6,0,0,0, +0,0,0,0,6,0,6,0,6,9,0,0,5,17,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,7,0,0, +0,0,0,7,0,0,0,0,16,5,0,0,0,0,0,0,0,4,0,0,0,5,11,5,0,7,0,0,0,4,8,7,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,7,0,0,0,0,12,0,0,0, +0,0,12,0,0,0,0,0,0,0,0,4,10,4,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,6,0,0,0,0,0,0,0,4,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,20,5,0,0, +10,0,0,0,0,0,0,0,0,0,0,6,0,0,0,6,12,0,0,0,0,0,0,6,0,0,0,0,0,0,9,4,10,7,0,4,0,0, +0,0,0,0,10,6,0,0,0,0,8,4,0,7,8,6,0,6,8,0,10,0,0,0,0,0,13,5,0,6,0,0,0,0,0,0,22,4, +0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,6,0,0,0,6,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,6,10, +5,8,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,10,4,0,0,10,7,0,0,0,0,0,5,0, +5,8,0,0,0,0,6,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,10,7,0,0,0,4,0,0,0,0,0,6,0,0, +0,0,0,0,0,0,8,7,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,7,0,0,0,6,0,0,0,0,0,0,0,0,0, +4,0,0,0,4,10,0,0,6,13,7,8,0,0,0,0,0,0,7,0,0,12,7,0,0,0,0,0,0,10,5,0,0,0,0,0,6,0, +0,0,0,0,0,0,0,0,0,13,7,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,6,0,0,0,0,0,0,0,0,8,6,0,6, +0,0,0,0,0,0,0,0,12,0,8,4,0,0,0,0,0,4,0,4,0,0,0,0,0,0,0,5,0,0,0,0,12,5,0,0,0,7,0, +0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,10,0,0,0,20,0,0,5,0,0,10, +7,11,7,0,0,0,0,0,0,0,0,0,0,17,0,9,4,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,5,0,0,10,7,0,4,0,6,0,0,24,0,0,5,0,0,0,0,8,0,0, +0,0,0,0,0,10,5,0,4,0,6,0,0,8,0,0,0,0,0,0,4,0,6,0,0,0,0,0,0,9,5,0,0,0,0,0,0,0,0, +0,0,0,6,0,0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,4,0,7, +0,0,13,0,0,0,0,0,0,0,11,6,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0, +17,7,0,0,11,6,0,0,0,0,12,6,0,0,0,6,0,6,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,0,0,0,6,0,0,0,0,0,0,0,0,0,0,10,0,0,4,8,6,0,0,0, +0,0,0,9,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,9,5,0,7,18,0,0,0,0,0,0,0,0,0,0,0,0,0,8,6,0,0,0,0,0,0,0,0,8,0,0,0, +0,0,0,0,0,5,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,6,0,0,0,0,0,0, +0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,4,0,6,0,0,9,0,0,0,0,0,0,0,0,0,13,0,0,0,0,0,0,0,0, +0,0,0,8,7,10,0,8,5,0,0,0,0,0,0,0,0,9,0,0,0,10,0,0,0,0,6,0,7,0,4,0,0,0,0,0,0,0,0, +8,0,0,0,0,0,8,4,0,0,0,0,0,5,0,0,10,0,12,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +4,0,0,0,0,0,0,12,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,18,6,11,0,0, +7,0,0,0,0,0,6,10,5,0,0,0,0,0,0,0,0,0,5,0,0,9,5,12,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,6,0,0,0,0,13,6,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0, +0,0,0,8,4,0,6,12,0,0,0,0,0,0,0,0,0,0,0,0,6,0,6,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,11,4,0,0,0,6,14,0,11,0,9,6,0,0,0,0,0,0,22,0,12,0,8,6,0,0,0,0,0,0,0,6,0, +0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0, +10,7,0,0,0,0,0,0,0,0,9,0,0,0,0,4,0,0,0,0,0,0,0,0,0,5,11,0,0,0,0,0,0,0,8,6,0,0,9, +7,0,0,12,4,0,0,0,0,0,0,12,6,0,6,0,7,0,0,8,5,0,0,0,0}; diff --git a/packages/runtime/vendor/brotli/c/enc/encode.c b/packages/runtime/vendor/brotli/c/enc/encode.c new file mode 100644 index 000000000..ba21aa2ec --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/encode.c @@ -0,0 +1,2021 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Implementation of Brotli compressor. */ + +#include + +#include "../common/constants.h" +#include "../common/context.h" +#include "../common/platform.h" +#include +#include "../common/version.h" +#include "backward_references_hq.h" +#include "backward_references.h" +#include "bit_cost.h" +#include "brotli_bit_stream.h" +#include "command.h" +#include "compound_dictionary.h" +#include "compress_fragment_two_pass.h" +#include "compress_fragment.h" +#include "dictionary_hash.h" +#include "encoder_dict.h" +#include "fast_log.h" +#include "hash.h" +#include "histogram.h" +#include "memory.h" +#include "metablock.h" +#include "params.h" +#include "quality.h" +#include "ringbuffer.h" +#include "state.h" +#include "static_init.h" +#include "utf8_util.h" +#include "write_bits.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define COPY_ARRAY(dst, src) memcpy(dst, src, sizeof(src)); + +static size_t InputBlockSize(BrotliEncoderState* s) { + return (size_t)1 << s->params.lgblock; +} + +static uint64_t UnprocessedInputSize(BrotliEncoderState* s) { + return s->input_pos_ - s->last_processed_pos_; +} + +static size_t RemainingInputBlockSize(BrotliEncoderState* s) { + const uint64_t delta = UnprocessedInputSize(s); + size_t block_size = InputBlockSize(s); + if (delta >= block_size) return 0; + return block_size - (size_t)delta; +} + +BROTLI_BOOL BrotliEncoderSetParameter( + BrotliEncoderState* state, BrotliEncoderParameter p, uint32_t value) { + /* Changing parameters on the fly is not implemented yet. */ + if (state->is_initialized_) return BROTLI_FALSE; + /* TODO(eustas): Validate/clamp parameters here. */ + switch (p) { + case BROTLI_PARAM_MODE: + state->params.mode = (BrotliEncoderMode)value; + return BROTLI_TRUE; + + case BROTLI_PARAM_QUALITY: + state->params.quality = (int)value; + return BROTLI_TRUE; + + case BROTLI_PARAM_LGWIN: + state->params.lgwin = (int)value; + return BROTLI_TRUE; + + case BROTLI_PARAM_LGBLOCK: + state->params.lgblock = (int)value; + return BROTLI_TRUE; + + case BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING: + if ((value != 0) && (value != 1)) return BROTLI_FALSE; + state->params.disable_literal_context_modeling = TO_BROTLI_BOOL(!!value); + return BROTLI_TRUE; + + case BROTLI_PARAM_SIZE_HINT: + state->params.size_hint = value; + return BROTLI_TRUE; + + case BROTLI_PARAM_LARGE_WINDOW: + state->params.large_window = TO_BROTLI_BOOL(!!value); + return BROTLI_TRUE; + + case BROTLI_PARAM_NPOSTFIX: + state->params.dist.distance_postfix_bits = value; + return BROTLI_TRUE; + + case BROTLI_PARAM_NDIRECT: + state->params.dist.num_direct_distance_codes = value; + return BROTLI_TRUE; + + case BROTLI_PARAM_STREAM_OFFSET: + if (value > (1u << 30)) return BROTLI_FALSE; + state->params.stream_offset = value; + return BROTLI_TRUE; + + default: return BROTLI_FALSE; + } +} + +/* Wraps 64-bit input position to 32-bit ring-buffer position preserving + "not-a-first-lap" feature. */ +static uint32_t WrapPosition(uint64_t position) { + uint32_t result = (uint32_t)position; + uint64_t gb = position >> 30; + if (gb > 2) { + /* Wrap every 2GiB; The first 3GB are continuous. */ + result = (result & ((1u << 30) - 1)) | ((uint32_t)((gb - 1) & 1) + 1) << 30; + } + return result; +} + +static uint8_t* GetBrotliStorage(BrotliEncoderState* s, size_t size) { + MemoryManager* m = &s->memory_manager_; + if (s->storage_size_ < size) { + BROTLI_FREE(m, s->storage_); + s->storage_ = BROTLI_ALLOC(m, uint8_t, size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->storage_)) return NULL; + s->storage_size_ = size; + } + return s->storage_; +} + +static size_t HashTableSize(size_t max_table_size, size_t input_size) { + size_t htsize = 256; + while (htsize < max_table_size && htsize < input_size) { + htsize <<= 1; + } + return htsize; +} + +static int* GetHashTable(BrotliEncoderState* s, int quality, + size_t input_size, size_t* table_size) { + /* Use smaller hash table when input.size() is smaller, since we + fill the table, incurring O(hash table size) overhead for + compression, and if the input is short, we won't need that + many hash table entries anyway. */ + MemoryManager* m = &s->memory_manager_; + const size_t max_table_size = MaxHashTableSize(quality); + size_t htsize = HashTableSize(max_table_size, input_size); + int* table; + BROTLI_DCHECK(max_table_size >= 256); + if (quality == FAST_ONE_PASS_COMPRESSION_QUALITY) { + /* Only odd shifts are supported by fast-one-pass. */ + if ((htsize & 0xAAAAA) == 0) { + htsize <<= 1; + } + } + + if (htsize <= sizeof(s->small_table_) / sizeof(s->small_table_[0])) { + table = s->small_table_; + } else { + if (htsize > s->large_table_size_) { + s->large_table_size_ = htsize; + BROTLI_FREE(m, s->large_table_); + s->large_table_ = BROTLI_ALLOC(m, int, htsize); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->large_table_)) return 0; + } + table = s->large_table_; + } + + *table_size = htsize; + memset(table, 0, htsize * sizeof(*table)); + return table; +} + +static void EncodeWindowBits(int lgwin, BROTLI_BOOL large_window, + uint16_t* last_bytes, uint8_t* last_bytes_bits) { + if (large_window) { + *last_bytes = (uint16_t)(((lgwin & 0x3F) << 8) | 0x11); + *last_bytes_bits = 14; + } else { + if (lgwin == 16) { + *last_bytes = 0; + *last_bytes_bits = 1; + } else if (lgwin == 17) { + *last_bytes = 1; + *last_bytes_bits = 7; + } else if (lgwin > 17) { + *last_bytes = (uint16_t)(((lgwin - 17) << 1) | 0x01); + *last_bytes_bits = 4; + } else { + *last_bytes = (uint16_t)(((lgwin - 8) << 4) | 0x01); + *last_bytes_bits = 7; + } + } +} + +/* TODO(eustas): move to compress_fragment.c? */ +/* Initializes the command and distance prefix codes for the first block. */ +static void InitCommandPrefixCodes(BrotliOnePassArena* s) { + static const BROTLI_MODEL("small") uint8_t kDefaultCommandDepths[128] = { + 0, 4, 4, 5, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, + 0, 0, 0, 4, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, + 7, 7, 10, 10, 10, 10, 10, 10, 0, 4, 4, 5, 5, 5, 6, 6, + 7, 8, 8, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, + 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 10, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + }; + static const BROTLI_MODEL("small") uint16_t kDefaultCommandBits[128] = { + 0, 0, 8, 9, 3, 35, 7, 71, + 39, 103, 23, 47, 175, 111, 239, 31, + 0, 0, 0, 4, 12, 2, 10, 6, + 13, 29, 11, 43, 27, 59, 87, 55, + 15, 79, 319, 831, 191, 703, 447, 959, + 0, 14, 1, 25, 5, 21, 19, 51, + 119, 159, 95, 223, 479, 991, 63, 575, + 127, 639, 383, 895, 255, 767, 511, 1023, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 27, 59, 7, 39, 23, 55, 30, 1, 17, 9, 25, 5, 0, 8, 4, 12, + 2, 10, 6, 21, 13, 29, 3, 19, 11, 15, 47, 31, 95, 63, 127, 255, + 767, 2815, 1791, 3839, 511, 2559, 1535, 3583, 1023, 3071, 2047, 4095, + }; + static const BROTLI_MODEL("small") uint8_t kDefaultCommandCode[] = { + 0xff, 0x77, 0xd5, 0xbf, 0xe7, 0xde, 0xea, 0x9e, 0x51, 0x5d, 0xde, 0xc6, + 0x70, 0x57, 0xbc, 0x58, 0x58, 0x58, 0xd8, 0xd8, 0x58, 0xd5, 0xcb, 0x8c, + 0xea, 0xe0, 0xc3, 0x87, 0x1f, 0x83, 0xc1, 0x60, 0x1c, 0x67, 0xb2, 0xaa, + 0x06, 0x83, 0xc1, 0x60, 0x30, 0x18, 0xcc, 0xa1, 0xce, 0x88, 0x54, 0x94, + 0x46, 0xe1, 0xb0, 0xd0, 0x4e, 0xb2, 0xf7, 0x04, 0x00, + }; + static const size_t kDefaultCommandCodeNumBits = 448; + COPY_ARRAY(s->cmd_depth, kDefaultCommandDepths); + COPY_ARRAY(s->cmd_bits, kDefaultCommandBits); + + /* Initialize the pre-compressed form of the command and distance prefix + codes. */ + COPY_ARRAY(s->cmd_code, kDefaultCommandCode); + s->cmd_code_numbits = kDefaultCommandCodeNumBits; +} + +/* TODO(eustas): avoid FP calculations. */ +static double EstimateEntropy(const uint32_t* population, size_t size) { + size_t total = 0; + double result = 0; + for (size_t i = 0; i < size; ++i) { + uint32_t p = population[i]; + total += p; + result += (double)p * FastLog2(p); + } + result = (double)total * FastLog2(total) - result; + return result; +} + +/* Decide about the context map based on the ability of the prediction + ability of the previous byte UTF8-prefix on the next byte. The + prediction ability is calculated as Shannon entropy. Here we need + Shannon entropy instead of 'BrotliBitsEntropy' since the prefix will be + encoded with the remaining 6 bits of the following byte, and + BrotliBitsEntropy will assume that symbol to be stored alone using Huffman + coding. */ +static void ChooseContextMap(int quality, + uint32_t* bigram_histo, + size_t* num_literal_contexts, + const uint32_t** literal_context_map) { + static const BROTLI_MODEL("small") + uint32_t kStaticContextMapContinuation[64] = { + 1, 1, 2, 2, 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, + }; + static const BROTLI_MODEL("small") + uint32_t kStaticContextMapSimpleUTF8[64] = { + 0, 0, 1, 1, 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, + }; + + uint32_t monogram_histo[3] = { 0 }; + uint32_t two_prefix_histo[6] = { 0 }; + size_t total; + size_t i; + double entropy[4]; + for (i = 0; i < 9; ++i) { + monogram_histo[i % 3] += bigram_histo[i]; + two_prefix_histo[i % 6] += bigram_histo[i]; + } + entropy[1] = EstimateEntropy(monogram_histo, 3); + entropy[2] = (EstimateEntropy(two_prefix_histo, 3) + + EstimateEntropy(two_prefix_histo + 3, 3)); + entropy[3] = 0; + for (i = 0; i < 3; ++i) { + entropy[3] += EstimateEntropy(bigram_histo + 3 * i, 3); + } + + total = monogram_histo[0] + monogram_histo[1] + monogram_histo[2]; + BROTLI_DCHECK(total != 0); + entropy[0] = 1.0 / (double)total; + entropy[1] *= entropy[0]; + entropy[2] *= entropy[0]; + entropy[3] *= entropy[0]; + + if (quality < MIN_QUALITY_FOR_HQ_CONTEXT_MODELING) { + /* 3 context models is a bit slower, don't use it at lower qualities. */ + entropy[3] = entropy[1] * 10; + } + /* If expected savings by symbol are less than 0.2 bits, skip the + context modeling -- in exchange for faster decoding speed. */ + if (entropy[1] - entropy[2] < 0.2 && + entropy[1] - entropy[3] < 0.2) { + *num_literal_contexts = 1; + } else if (entropy[2] - entropy[3] < 0.02) { + *num_literal_contexts = 2; + *literal_context_map = kStaticContextMapSimpleUTF8; + } else { + *num_literal_contexts = 3; + *literal_context_map = kStaticContextMapContinuation; + } +} + +/* Decide if we want to use a more complex static context map containing 13 + context values, based on the entropy reduction of histograms over the + first 5 bits of literals. */ +static BROTLI_BOOL ShouldUseComplexStaticContextMap(const uint8_t* input, + size_t start_pos, size_t length, size_t mask, int quality, size_t size_hint, + size_t* num_literal_contexts, const uint32_t** literal_context_map, + uint32_t* arena) { + static const BROTLI_MODEL("small") + uint32_t kStaticContextMapComplexUTF8[64] = { + 11, 11, 12, 12, /* 0 special */ + 0, 0, 0, 0, /* 4 lf */ + 1, 1, 9, 9, /* 8 space */ + 2, 2, 2, 2, /* !, first after space/lf and after something else. */ + 1, 1, 1, 1, /* " */ + 8, 3, 3, 3, /* % */ + 1, 1, 1, 1, /* ({[ */ + 2, 2, 2, 2, /* }]) */ + 8, 4, 4, 4, /* :; */ + 8, 7, 4, 4, /* . */ + 8, 0, 0, 0, /* > */ + 3, 3, 3, 3, /* [0..9] */ + 5, 5, 10, 5, /* [A-Z] */ + 5, 5, 10, 5, + 6, 6, 6, 6, /* [a-z] */ + 6, 6, 6, 6, + }; + BROTLI_UNUSED(quality); + /* Try the more complex static context map only for long data. */ + if (size_hint < (1 << 20)) { + return BROTLI_FALSE; + } else { + const size_t end_pos = start_pos + length; + /* To make entropy calculations faster, we collect histograms + over the 5 most significant bits of literals. One histogram + without context and 13 additional histograms for each context value. */ + uint32_t* BROTLI_RESTRICT const combined_histo = arena; + uint32_t* BROTLI_RESTRICT const context_histo = arena + 32; + uint32_t total = 0; + double entropy[3]; + size_t i; + ContextLut utf8_lut = BROTLI_CONTEXT_LUT(CONTEXT_UTF8); + memset(arena, 0, sizeof(arena[0]) * 32 * (BROTLI_MAX_STATIC_CONTEXTS + 1)); + for (; start_pos + 64 <= end_pos; start_pos += 4096) { + const size_t stride_end_pos = start_pos + 64; + uint8_t prev2 = input[start_pos & mask]; + uint8_t prev1 = input[(start_pos + 1) & mask]; + size_t pos; + /* To make the analysis of the data faster we only examine 64 byte long + strides at every 4kB intervals. */ + for (pos = start_pos + 2; pos < stride_end_pos; ++pos) { + const uint8_t literal = input[pos & mask]; + const uint8_t context = (uint8_t)kStaticContextMapComplexUTF8[ + BROTLI_CONTEXT(prev1, prev2, utf8_lut)]; + ++total; + ++combined_histo[literal >> 3]; + ++context_histo[(context << 5) + (literal >> 3)]; + prev2 = prev1; + prev1 = literal; + } + } + entropy[1] = EstimateEntropy(combined_histo, 32); + entropy[2] = 0; + for (i = 0; i < BROTLI_MAX_STATIC_CONTEXTS; ++i) { + entropy[2] += EstimateEntropy(context_histo + (i << 5), 32); + } + entropy[0] = 1.0 / (double)total; + entropy[1] *= entropy[0]; + entropy[2] *= entropy[0]; + /* The triggering heuristics below were tuned by compressing the individual + files of the silesia corpus. If we skip this kind of context modeling + for not very well compressible input (i.e. entropy using context modeling + is 60% of maximal entropy) or if expected savings by symbol are less + than 0.2 bits, then in every case when it triggers, the final compression + ratio is improved. Note however that this heuristics might be too strict + for some cases and could be tuned further. */ + if (entropy[2] > 3.0 || entropy[1] - entropy[2] < 0.2) { + return BROTLI_FALSE; + } else { + *num_literal_contexts = BROTLI_MAX_STATIC_CONTEXTS; + *literal_context_map = kStaticContextMapComplexUTF8; + return BROTLI_TRUE; + } + } +} + +static void DecideOverLiteralContextModeling(const uint8_t* input, + size_t start_pos, size_t length, size_t mask, int quality, size_t size_hint, + size_t* num_literal_contexts, const uint32_t** literal_context_map, + uint32_t* arena) { + if (quality < MIN_QUALITY_FOR_CONTEXT_MODELING || length < 64) { + return; + } else if (ShouldUseComplexStaticContextMap( + input, start_pos, length, mask, quality, size_hint, + num_literal_contexts, literal_context_map, arena)) { + /* Context map was already set, nothing else to do. */ + } else { + /* Gather bi-gram data of the UTF8 byte prefixes. To make the analysis of + UTF8 data faster we only examine 64 byte long strides at every 4kB + intervals. */ + const size_t end_pos = start_pos + length; + uint32_t* BROTLI_RESTRICT const bigram_prefix_histo = arena; + memset(bigram_prefix_histo, 0, sizeof(arena[0]) * 9); + for (; start_pos + 64 <= end_pos; start_pos += 4096) { + static const int lut[4] = { 0, 0, 1, 2 }; + const size_t stride_end_pos = start_pos + 64; + int prev = lut[input[start_pos & mask] >> 6] * 3; + size_t pos; + for (pos = start_pos + 1; pos < stride_end_pos; ++pos) { + const uint8_t literal = input[pos & mask]; + ++bigram_prefix_histo[prev + lut[literal >> 6]]; + prev = lut[literal >> 6] * 3; + } + } + ChooseContextMap(quality, &bigram_prefix_histo[0], num_literal_contexts, + literal_context_map); + } +} + +static BROTLI_BOOL ShouldCompress( + const uint8_t* data, const size_t mask, const uint64_t last_flush_pos, + const size_t bytes, const size_t num_literals, const size_t num_commands) { + /* TODO(eustas): find more precise minimal block overhead. */ + if (bytes <= 2) return BROTLI_FALSE; + if (num_commands < (bytes >> 8) + 2) { + if ((double)num_literals > 0.99 * (double)bytes) { + uint32_t literal_histo[256] = { 0 }; + static const uint32_t kSampleRate = 13; + static const double kInvSampleRate = 1.0 / 13.0; + static const double kMinEntropy = 7.92; + const double bit_cost_threshold = + (double)bytes * kMinEntropy * kInvSampleRate; + size_t t = (bytes + kSampleRate - 1) / kSampleRate; + uint32_t pos = (uint32_t)last_flush_pos; + size_t i; + for (i = 0; i < t; i++) { + ++literal_histo[data[pos & mask]]; + pos += kSampleRate; + } + if (BrotliBitsEntropy(literal_histo, 256) > bit_cost_threshold) { + return BROTLI_FALSE; + } + } + } + return BROTLI_TRUE; +} + +/* Chooses the literal context mode for a metablock */ +static ContextType ChooseContextMode(const BrotliEncoderParams* params, + const uint8_t* data, const size_t pos, const size_t mask, + const size_t length) { + /* We only do the computation for the option of something else than + CONTEXT_UTF8 for the highest qualities */ + if (params->quality >= MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING && + !BrotliIsMostlyUTF8(data, pos, mask, length, kMinUTF8Ratio)) { + return CONTEXT_SIGNED; + } + return CONTEXT_UTF8; +} + +static void WriteMetaBlockInternal(MemoryManager* m, + const uint8_t* data, + const size_t mask, + const uint64_t last_flush_pos, + const size_t bytes, + const BROTLI_BOOL is_last, + ContextType literal_context_mode, + const BrotliEncoderParams* params, + const uint8_t prev_byte, + const uint8_t prev_byte2, + const size_t num_literals, + const size_t num_commands, + Command* commands, + const int* saved_dist_cache, + int* dist_cache, + size_t* storage_ix, + uint8_t* storage) { + const uint32_t wrapped_last_flush_pos = WrapPosition(last_flush_pos); + uint16_t last_bytes; + uint8_t last_bytes_bits; + ContextLut literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode); + BrotliEncoderParams block_params = *params; + + if (bytes == 0) { + /* Write the ISLAST and ISEMPTY bits. */ + BrotliWriteBits(2, 3, storage_ix, storage); + *storage_ix = (*storage_ix + 7u) & ~7u; + return; + } + + if (!ShouldCompress(data, mask, last_flush_pos, bytes, + num_literals, num_commands)) { + /* Restore the distance cache, as its last update by + CreateBackwardReferences is now unused. */ + memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0])); + BrotliStoreUncompressedMetaBlock(is_last, data, + wrapped_last_flush_pos, mask, bytes, + storage_ix, storage); + return; + } + + BROTLI_DCHECK(*storage_ix <= 14); + last_bytes = (uint16_t)((storage[1] << 8) | storage[0]); + last_bytes_bits = (uint8_t)(*storage_ix); + if (params->quality <= MAX_QUALITY_FOR_STATIC_ENTROPY_CODES) { + BrotliStoreMetaBlockFast(m, data, wrapped_last_flush_pos, + bytes, mask, is_last, params, + commands, num_commands, + storage_ix, storage); + if (BROTLI_IS_OOM(m)) return; + } else if (params->quality < MIN_QUALITY_FOR_BLOCK_SPLIT) { + BrotliStoreMetaBlockTrivial(m, data, wrapped_last_flush_pos, + bytes, mask, is_last, params, + commands, num_commands, + storage_ix, storage); + if (BROTLI_IS_OOM(m)) return; + } else { + MetaBlockSplit mb; + InitMetaBlockSplit(&mb); + if (params->quality < MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING) { + size_t num_literal_contexts = 1; + const uint32_t* literal_context_map = NULL; + if (!params->disable_literal_context_modeling) { + /* TODO(eustas): pull to higher level and reuse. */ + uint32_t* arena = + BROTLI_ALLOC(m, uint32_t, 32 * (BROTLI_MAX_STATIC_CONTEXTS + 1)); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(arena)) return; + DecideOverLiteralContextModeling( + data, wrapped_last_flush_pos, bytes, mask, params->quality, + params->size_hint, &num_literal_contexts, + &literal_context_map, arena); + BROTLI_FREE(m, arena); + } + BrotliBuildMetaBlockGreedy(m, data, wrapped_last_flush_pos, mask, + prev_byte, prev_byte2, literal_context_lut, num_literal_contexts, + literal_context_map, commands, num_commands, &mb); + if (BROTLI_IS_OOM(m)) return; + } else { + BrotliBuildMetaBlock(m, data, wrapped_last_flush_pos, mask, &block_params, + prev_byte, prev_byte2, + commands, num_commands, + literal_context_mode, + &mb); + if (BROTLI_IS_OOM(m)) return; + } + if (params->quality >= MIN_QUALITY_FOR_OPTIMIZE_HISTOGRAMS) { + /* The number of distance symbols effectively used for distance + histograms. It might be less than distance alphabet size + for "Large Window Brotli" (32-bit). */ + BrotliOptimizeHistograms(block_params.dist.alphabet_size_limit, &mb); + } + BrotliStoreMetaBlock(m, data, wrapped_last_flush_pos, bytes, mask, + prev_byte, prev_byte2, + is_last, + &block_params, + literal_context_mode, + commands, num_commands, + &mb, + storage_ix, storage); + if (BROTLI_IS_OOM(m)) return; + DestroyMetaBlockSplit(m, &mb); + } + if (bytes + 4 < (*storage_ix >> 3)) { + /* Restore the distance cache and last byte. */ + memcpy(dist_cache, saved_dist_cache, 4 * sizeof(dist_cache[0])); + storage[0] = (uint8_t)last_bytes; + storage[1] = (uint8_t)(last_bytes >> 8); + *storage_ix = last_bytes_bits; + BrotliStoreUncompressedMetaBlock(is_last, data, + wrapped_last_flush_pos, mask, + bytes, storage_ix, storage); + } +} + +static void ChooseDistanceParams(BrotliEncoderParams* params) { + uint32_t distance_postfix_bits = 0; + uint32_t num_direct_distance_codes = 0; + + if (params->quality >= MIN_QUALITY_FOR_NONZERO_DISTANCE_PARAMS) { + uint32_t ndirect_msb; + if (params->mode == BROTLI_MODE_FONT) { + distance_postfix_bits = 1; + num_direct_distance_codes = 12; + } else { + distance_postfix_bits = params->dist.distance_postfix_bits; + num_direct_distance_codes = params->dist.num_direct_distance_codes; + } + ndirect_msb = (num_direct_distance_codes >> distance_postfix_bits) & 0x0F; + if (distance_postfix_bits > BROTLI_MAX_NPOSTFIX || + num_direct_distance_codes > BROTLI_MAX_NDIRECT || + (ndirect_msb << distance_postfix_bits) != num_direct_distance_codes) { + distance_postfix_bits = 0; + num_direct_distance_codes = 0; + } + } + + BrotliInitDistanceParams(¶ms->dist, distance_postfix_bits, + num_direct_distance_codes, params->large_window); +} + +static BROTLI_BOOL EnsureInitialized(BrotliEncoderState* s) { + MemoryManager* m = &s->memory_manager_; + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + if (s->is_initialized_) return BROTLI_TRUE; + + s->last_bytes_bits_ = 0; + s->last_bytes_ = 0; + s->flint_ = BROTLI_FLINT_DONE; + s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX; + + SanitizeParams(&s->params); + s->params.lgblock = ComputeLgBlock(&s->params); + ChooseDistanceParams(&s->params); + + if (s->params.stream_offset != 0) { + s->flint_ = BROTLI_FLINT_NEEDS_2_BYTES; + /* Poison the distance cache. -16 +- 3 is still less than zero (invalid). */ + s->dist_cache_[0] = -16; + s->dist_cache_[1] = -16; + s->dist_cache_[2] = -16; + s->dist_cache_[3] = -16; + memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_)); + } + + RingBufferSetup(&s->params, &s->ringbuffer_); + + /* Initialize last byte with stream header. */ + { + int lgwin = s->params.lgwin; + if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY || + s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) { + lgwin = BROTLI_MAX(int, lgwin, 18); + } + if (s->params.stream_offset == 0) { + EncodeWindowBits(lgwin, s->params.large_window, + &s->last_bytes_, &s->last_bytes_bits_); + } else { + /* Bigger values have the same effect, but could cause overflows. */ + s->params.stream_offset = BROTLI_MIN(size_t, + s->params.stream_offset, BROTLI_MAX_BACKWARD_LIMIT(lgwin)); + } + } + + if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) { + s->one_pass_arena_ = BROTLI_ALLOC(m, BrotliOnePassArena, 1); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + InitCommandPrefixCodes(s->one_pass_arena_); + } else if (s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) { + s->two_pass_arena_ = BROTLI_ALLOC(m, BrotliTwoPassArena, 1); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + } + + s->is_initialized_ = BROTLI_TRUE; + return BROTLI_TRUE; +} + +static void BrotliEncoderInitParams(BrotliEncoderParams* params) { + params->mode = BROTLI_DEFAULT_MODE; + params->large_window = BROTLI_FALSE; + params->quality = BROTLI_DEFAULT_QUALITY; + params->lgwin = BROTLI_DEFAULT_WINDOW; + params->lgblock = 0; + params->stream_offset = 0; + params->size_hint = 0; + params->disable_literal_context_modeling = BROTLI_FALSE; + BrotliInitSharedEncoderDictionary(¶ms->dictionary); + params->dist.distance_postfix_bits = 0; + params->dist.num_direct_distance_codes = 0; + params->dist.alphabet_size_max = + BROTLI_DISTANCE_ALPHABET_SIZE(0, 0, BROTLI_MAX_DISTANCE_BITS); + params->dist.alphabet_size_limit = params->dist.alphabet_size_max; + params->dist.max_distance = BROTLI_MAX_DISTANCE; +} + +static void BrotliEncoderCleanupParams(MemoryManager* m, + BrotliEncoderParams* params) { + BrotliCleanupSharedEncoderDictionary(m, ¶ms->dictionary); +} + +#ifdef BROTLI_REPORTING +/* When BROTLI_REPORTING is defined extra reporting module have to be linked. */ +void BrotliEncoderOnStart(const BrotliEncoderState* s); +void BrotliEncoderOnFinish(const BrotliEncoderState* s); +#define BROTLI_ENCODER_ON_START(s) BrotliEncoderOnStart(s); +#define BROTLI_ENCODER_ON_FINISH(s) BrotliEncoderOnFinish(s); +#else +#if !defined(BROTLI_ENCODER_ON_START) +#define BROTLI_ENCODER_ON_START(s) (void)(s); +#endif +#if !defined(BROTLI_ENCODER_ON_FINISH) +#define BROTLI_ENCODER_ON_FINISH(s) (void)(s); +#endif +#endif + +static void BrotliEncoderInitState(BrotliEncoderState* s) { + BROTLI_ENCODER_ON_START(s); + BrotliEncoderInitParams(&s->params); + s->input_pos_ = 0; + s->num_commands_ = 0; + s->num_literals_ = 0; + s->last_insert_len_ = 0; + s->last_flush_pos_ = 0; + s->last_processed_pos_ = 0; + s->prev_byte_ = 0; + s->prev_byte2_ = 0; + s->storage_size_ = 0; + s->storage_ = 0; + HasherInit(&s->hasher_); + s->large_table_ = NULL; + s->large_table_size_ = 0; + s->one_pass_arena_ = NULL; + s->two_pass_arena_ = NULL; + s->command_buf_ = NULL; + s->literal_buf_ = NULL; + s->total_in_ = 0; + s->next_out_ = NULL; + s->available_out_ = 0; + s->total_out_ = 0; + s->stream_state_ = BROTLI_STREAM_PROCESSING; + s->is_last_block_emitted_ = BROTLI_FALSE; + s->is_initialized_ = BROTLI_FALSE; + + RingBufferInit(&s->ringbuffer_); + + s->commands_ = 0; + s->cmd_alloc_size_ = 0; + + /* Initialize distance cache. */ + s->dist_cache_[0] = 4; + s->dist_cache_[1] = 11; + s->dist_cache_[2] = 15; + s->dist_cache_[3] = 16; + /* Save the state of the distance cache in case we need to restore it for + emitting an uncompressed block. */ + memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_)); +} + +BrotliEncoderState* BrotliEncoderCreateInstance( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + BROTLI_BOOL healthy = BrotliEncoderEnsureStaticInit(); + if (!healthy) { + return 0; + } + BrotliEncoderState* state = (BrotliEncoderState*)BrotliBootstrapAlloc( + sizeof(BrotliEncoderState), alloc_func, free_func, opaque); + if (state == NULL) { + /* BROTLI_DUMP(); */ + return 0; + } + BrotliInitMemoryManager( + &state->memory_manager_, alloc_func, free_func, opaque); + BrotliEncoderInitState(state); + return state; +} + +static void BrotliEncoderCleanupState(BrotliEncoderState* s) { + MemoryManager* m = &s->memory_manager_; + + BROTLI_ENCODER_ON_FINISH(s); + + if (BROTLI_IS_OOM(m)) { + BrotliWipeOutMemoryManager(m); + return; + } + + BROTLI_FREE(m, s->storage_); + BROTLI_FREE(m, s->commands_); + RingBufferFree(m, &s->ringbuffer_); + DestroyHasher(m, &s->hasher_); + BROTLI_FREE(m, s->large_table_); + BROTLI_FREE(m, s->one_pass_arena_); + BROTLI_FREE(m, s->two_pass_arena_); + BROTLI_FREE(m, s->command_buf_); + BROTLI_FREE(m, s->literal_buf_); + BrotliEncoderCleanupParams(m, &s->params); +} + +/* Deinitializes and frees BrotliEncoderState instance. */ +void BrotliEncoderDestroyInstance(BrotliEncoderState* state) { + if (!state) { + return; + } else { + BrotliEncoderCleanupState(state); + BrotliBootstrapFree(state, &state->memory_manager_); + } +} + +/* + Copies the given input data to the internal ring buffer of the compressor. + No processing of the data occurs at this time and this function can be + called multiple times before calling WriteBrotliData() to process the + accumulated input. At most input_block_size() bytes of input data can be + copied to the ring buffer, otherwise the next WriteBrotliData() will fail. + */ +static void CopyInputToRingBuffer(BrotliEncoderState* s, + const size_t input_size, + const uint8_t* input_buffer) { + RingBuffer* ringbuffer_ = &s->ringbuffer_; + MemoryManager* m = &s->memory_manager_; + RingBufferWrite(m, input_buffer, input_size, ringbuffer_); + if (BROTLI_IS_OOM(m)) return; + s->input_pos_ += input_size; + + /* TL;DR: If needed, initialize 7 more bytes in the ring buffer to make the + hashing not depend on uninitialized data. This makes compression + deterministic and it prevents uninitialized memory warnings in Valgrind. + Even without erasing, the output would be valid (but nondeterministic). + + Background information: The compressor stores short (at most 8 bytes) + substrings of the input already read in a hash table, and detects + repetitions by looking up such substrings in the hash table. If it + can find a substring, it checks whether the substring is really there + in the ring buffer (or it's just a hash collision). Should the hash + table become corrupt, this check makes sure that the output is + still valid, albeit the compression ratio would be bad. + + The compressor populates the hash table from the ring buffer as it's + reading new bytes from the input. However, at the last few indexes of + the ring buffer, there are not enough bytes to build full-length + substrings from. Since the hash table always contains full-length + substrings, we overwrite with zeros here to make sure that those + substrings will contain zeros at the end instead of uninitialized + data. + + Please note that erasing is not necessary (because the + memory region is already initialized since he ring buffer + has a `tail' that holds a copy of the beginning,) so we + skip erasing if we have already gone around at least once in + the ring buffer. + + Only clear during the first round of ring-buffer writes. On + subsequent rounds data in the ring-buffer would be affected. */ + if (ringbuffer_->pos_ <= ringbuffer_->mask_) { + /* This is the first time when the ring buffer is being written. + We clear 7 bytes just after the bytes that have been copied from + the input buffer. + + The ring-buffer has a "tail" that holds a copy of the beginning, + but only once the ring buffer has been fully written once, i.e., + pos <= mask. For the first time, we need to write values + in this tail (where index may be larger than mask), so that + we have exactly defined behavior and don't read uninitialized + memory. Due to performance reasons, hashing reads data using a + LOAD64, which can go 7 bytes beyond the bytes written in the + ring-buffer. */ + memset(ringbuffer_->buffer_ + ringbuffer_->pos_, 0, 7); + } +} + +/* Marks all input as processed. + Returns true if position wrapping occurs. */ +static BROTLI_BOOL UpdateLastProcessedPos(BrotliEncoderState* s) { + uint32_t wrapped_last_processed_pos = WrapPosition(s->last_processed_pos_); + uint32_t wrapped_input_pos = WrapPosition(s->input_pos_); + s->last_processed_pos_ = s->input_pos_; + return TO_BROTLI_BOOL(wrapped_input_pos < wrapped_last_processed_pos); +} + +static void ExtendLastCommand(BrotliEncoderState* s, uint32_t* bytes, + uint32_t* wrapped_last_processed_pos) { + Command* last_command = &s->commands_[s->num_commands_ - 1]; + const uint8_t* data = s->ringbuffer_.buffer_; + const uint32_t mask = s->ringbuffer_.mask_; + uint64_t max_backward_distance = + (((uint64_t)1) << s->params.lgwin) - BROTLI_WINDOW_GAP; + uint64_t last_copy_len = last_command->copy_len_ & 0x1FFFFFF; + uint64_t last_processed_pos = s->last_processed_pos_ - last_copy_len; + uint64_t max_distance = last_processed_pos < max_backward_distance ? + last_processed_pos : max_backward_distance; + uint64_t cmd_dist = (uint64_t)s->dist_cache_[0]; + uint32_t distance_code = CommandRestoreDistanceCode(last_command, + &s->params.dist); + const CompoundDictionary* dict = &s->params.dictionary.compound; + size_t compound_dictionary_size = dict->total_size; + if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES || + distance_code - (BROTLI_NUM_DISTANCE_SHORT_CODES - 1) == cmd_dist) { + if (cmd_dist <= max_distance) { + while (*bytes != 0 && data[*wrapped_last_processed_pos & mask] == + data[(*wrapped_last_processed_pos - cmd_dist) & mask]) { + last_command->copy_len_++; + (*bytes)--; + (*wrapped_last_processed_pos)++; + } + } else { + if ((cmd_dist - max_distance - 1) < compound_dictionary_size && + last_copy_len < cmd_dist - max_distance) { + size_t address = + compound_dictionary_size - (size_t)(cmd_dist - max_distance) + + (size_t)last_copy_len; + size_t br_index = 0; + size_t br_offset; + const uint8_t* chunk; + size_t chunk_length; + while (address >= dict->chunk_offsets[br_index + 1]) br_index++; + br_offset = address - dict->chunk_offsets[br_index]; + chunk = dict->chunk_source[br_index]; + chunk_length = + dict->chunk_offsets[br_index + 1] - dict->chunk_offsets[br_index]; + while (*bytes != 0 && data[*wrapped_last_processed_pos & mask] == + chunk[br_offset]) { + last_command->copy_len_++; + (*bytes)--; + (*wrapped_last_processed_pos)++; + if (++br_offset == chunk_length) { + br_index++; + br_offset = 0; + if (br_index != dict->num_chunks) { + chunk = dict->chunk_source[br_index]; + chunk_length = dict->chunk_offsets[br_index + 1] - + dict->chunk_offsets[br_index]; + } else { + break; + } + } + } + } + } + /* The copy length is at most the metablock size, and thus expressible. */ + GetLengthCode(last_command->insert_len_, + (size_t)((int)(last_command->copy_len_ & 0x1FFFFFF) + + (int)(last_command->copy_len_ >> 25)), + TO_BROTLI_BOOL((last_command->dist_prefix_ & 0x3FF) == 0), + &last_command->cmd_prefix_); + } +} + +/* + Processes the accumulated input data and sets |*out_size| to the length of + the new output meta-block, or to zero if no new output meta-block has been + created (in this case the processed input data is buffered internally). + If |*out_size| is positive, |*output| points to the start of the output + data. If |is_last| or |force_flush| is BROTLI_TRUE, an output meta-block is + always created. However, until |is_last| is BROTLI_TRUE encoder may retain up + to 7 bits of the last byte of output. Byte-alignment could be enforced by + emitting an empty meta-data block. + Returns BROTLI_FALSE if the size of the input data is larger than + input_block_size(). + */ +static BROTLI_BOOL EncodeData( + BrotliEncoderState* s, const BROTLI_BOOL is_last, + const BROTLI_BOOL force_flush, size_t* out_size, uint8_t** output) { + const uint64_t delta = UnprocessedInputSize(s); + uint32_t bytes = (uint32_t)delta; + uint32_t wrapped_last_processed_pos = WrapPosition(s->last_processed_pos_); + uint8_t* data; + uint32_t mask; + MemoryManager* m = &s->memory_manager_; + ContextType literal_context_mode; + ContextLut literal_context_lut; + BROTLI_BOOL fast_compress = + s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY || + s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY; + + data = s->ringbuffer_.buffer_; + mask = s->ringbuffer_.mask_; + + if (delta == 0) { /* No new input; still might want to flush or finish. */ + if (!data) { /* No input has been processed so far. */ + if (is_last) { /* Emit complete finalized stream. */ + BROTLI_DCHECK(s->last_bytes_bits_ <= 14); + s->last_bytes_ |= (uint16_t)(3u << s->last_bytes_bits_); + s->last_bytes_bits_ = (uint8_t)(s->last_bytes_bits_ + 2u); + s->tiny_buf_.u8[0] = (uint8_t)s->last_bytes_; + s->tiny_buf_.u8[1] = (uint8_t)(s->last_bytes_ >> 8); + *output = s->tiny_buf_.u8; + *out_size = (s->last_bytes_bits_ + 7u) >> 3u; + return BROTLI_TRUE; + } else { /* No data, not last -> no-op. */ + *out_size = 0; + return BROTLI_TRUE; + } + } else { + /* Fast compress performs flush every block -> flush is no-op. */ + if (!is_last && (!force_flush || fast_compress)) { /* Another no-op. */ + *out_size = 0; + return BROTLI_TRUE; + } + } + } + BROTLI_DCHECK(data); + + if (s->params.quality > s->params.dictionary.max_quality) return BROTLI_FALSE; + /* Adding more blocks after "last" block is forbidden. */ + if (s->is_last_block_emitted_) return BROTLI_FALSE; + if (is_last) s->is_last_block_emitted_ = BROTLI_TRUE; + + if (delta > InputBlockSize(s)) { + return BROTLI_FALSE; + } + if (s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY && + !s->command_buf_) { + s->command_buf_ = + BROTLI_ALLOC(m, uint32_t, kCompressFragmentTwoPassBlockSize); + s->literal_buf_ = + BROTLI_ALLOC(m, uint8_t, kCompressFragmentTwoPassBlockSize); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->command_buf_) || + BROTLI_IS_NULL(s->literal_buf_)) { + return BROTLI_FALSE; + } + } + + if (fast_compress) { + uint8_t* storage; + size_t storage_ix = s->last_bytes_bits_; + size_t table_size; + int* table; + + storage = GetBrotliStorage(s, 2 * bytes + 503); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + storage[0] = (uint8_t)s->last_bytes_; + storage[1] = (uint8_t)(s->last_bytes_ >> 8); + table = GetHashTable(s, s->params.quality, bytes, &table_size); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) { + BrotliCompressFragmentFast( + s->one_pass_arena_, &data[wrapped_last_processed_pos & mask], + bytes, is_last, + table, table_size, + &storage_ix, storage); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + } else { + BrotliCompressFragmentTwoPass( + s->two_pass_arena_, &data[wrapped_last_processed_pos & mask], + bytes, is_last, + s->command_buf_, s->literal_buf_, + table, table_size, + &storage_ix, storage); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + } + s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]); + s->last_bytes_bits_ = storage_ix & 7u; + UpdateLastProcessedPos(s); + *output = &storage[0]; + *out_size = storage_ix >> 3; + return BROTLI_TRUE; + } + + { + /* Theoretical max number of commands is 1 per 2 bytes. */ + size_t newsize = s->num_commands_ + bytes / 2 + 1; + if (newsize > s->cmd_alloc_size_) { + Command* new_commands; + /* Reserve a bit more memory to allow merging with a next block + without reallocation: that would impact speed. */ + newsize += (bytes / 4) + 16; + s->cmd_alloc_size_ = newsize; + new_commands = BROTLI_ALLOC(m, Command, newsize); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_commands)) return BROTLI_FALSE; + if (s->commands_) { + memcpy(new_commands, s->commands_, sizeof(Command) * s->num_commands_); + BROTLI_FREE(m, s->commands_); + } + s->commands_ = new_commands; + } + } + + InitOrStitchToPreviousBlock(m, &s->hasher_, data, mask, &s->params, + wrapped_last_processed_pos, bytes, is_last); + + literal_context_mode = ChooseContextMode( + &s->params, data, WrapPosition(s->last_flush_pos_), + mask, (size_t)(s->input_pos_ - s->last_flush_pos_)); + literal_context_lut = BROTLI_CONTEXT_LUT(literal_context_mode); + + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + + if (s->num_commands_ && s->last_insert_len_ == 0) { + ExtendLastCommand(s, &bytes, &wrapped_last_processed_pos); + } + + if (s->params.quality == ZOPFLIFICATION_QUALITY) { + BROTLI_DCHECK(s->params.hasher.type == 10); + BrotliCreateZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos, + data, mask, literal_context_lut, &s->params, + &s->hasher_, s->dist_cache_, + &s->last_insert_len_, &s->commands_[s->num_commands_], + &s->num_commands_, &s->num_literals_); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + } else if (s->params.quality == HQ_ZOPFLIFICATION_QUALITY) { + BROTLI_DCHECK(s->params.hasher.type == 10); + BrotliCreateHqZopfliBackwardReferences(m, bytes, wrapped_last_processed_pos, + data, mask, literal_context_lut, &s->params, + &s->hasher_, s->dist_cache_, + &s->last_insert_len_, &s->commands_[s->num_commands_], + &s->num_commands_, &s->num_literals_); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + } else { + BrotliCreateBackwardReferences(bytes, wrapped_last_processed_pos, + data, mask, literal_context_lut, &s->params, + &s->hasher_, s->dist_cache_, + &s->last_insert_len_, &s->commands_[s->num_commands_], + &s->num_commands_, &s->num_literals_); + } + + { + const size_t max_length = MaxMetablockSize(&s->params); + const size_t max_literals = max_length / 8; + const size_t max_commands = max_length / 8; + const size_t processed_bytes = (size_t)(s->input_pos_ - s->last_flush_pos_); + /* If maximal possible additional block doesn't fit metablock, flush now. */ + /* TODO(eustas): Postpone decision until next block arrives? */ + const BROTLI_BOOL next_input_fits_metablock = TO_BROTLI_BOOL( + processed_bytes + InputBlockSize(s) <= max_length); + /* If block splitting is not used, then flush as soon as there is some + amount of commands / literals produced. */ + const BROTLI_BOOL should_flush = TO_BROTLI_BOOL( + s->params.quality < MIN_QUALITY_FOR_BLOCK_SPLIT && + s->num_literals_ + s->num_commands_ >= MAX_NUM_DELAYED_SYMBOLS); + if (!is_last && !force_flush && !should_flush && + next_input_fits_metablock && + s->num_literals_ < max_literals && + s->num_commands_ < max_commands) { + /* Merge with next input block. Everything will happen later. */ + if (UpdateLastProcessedPos(s)) { + HasherReset(&s->hasher_); + } + *out_size = 0; + return BROTLI_TRUE; + } + } + + /* Create the last insert-only command. */ + if (s->last_insert_len_ > 0) { + InitInsertCommand(&s->commands_[s->num_commands_++], s->last_insert_len_); + s->num_literals_ += s->last_insert_len_; + s->last_insert_len_ = 0; + } + + if (!is_last && s->input_pos_ == s->last_flush_pos_) { + /* We have no new input data and we don't have to finish the stream, so + nothing to do. */ + *out_size = 0; + return BROTLI_TRUE; + } + BROTLI_DCHECK(s->input_pos_ >= s->last_flush_pos_); + BROTLI_DCHECK(s->input_pos_ > s->last_flush_pos_ || is_last); + BROTLI_DCHECK(s->input_pos_ - s->last_flush_pos_ <= 1u << 24); + { + const uint32_t metablock_size = + (uint32_t)(s->input_pos_ - s->last_flush_pos_); + uint8_t* storage = GetBrotliStorage(s, 2 * metablock_size + 503); + size_t storage_ix = s->last_bytes_bits_; + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + storage[0] = (uint8_t)s->last_bytes_; + storage[1] = (uint8_t)(s->last_bytes_ >> 8); + WriteMetaBlockInternal( + m, data, mask, s->last_flush_pos_, metablock_size, is_last, + literal_context_mode, &s->params, s->prev_byte_, s->prev_byte2_, + s->num_literals_, s->num_commands_, s->commands_, s->saved_dist_cache_, + s->dist_cache_, &storage_ix, storage); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]); + s->last_bytes_bits_ = storage_ix & 7u; + s->last_flush_pos_ = s->input_pos_; + if (UpdateLastProcessedPos(s)) { + HasherReset(&s->hasher_); + } + if (s->last_flush_pos_ > 0) { + s->prev_byte_ = data[((uint32_t)s->last_flush_pos_ - 1) & mask]; + } + if (s->last_flush_pos_ > 1) { + s->prev_byte2_ = data[(uint32_t)(s->last_flush_pos_ - 2) & mask]; + } + s->num_commands_ = 0; + s->num_literals_ = 0; + /* Save the state of the distance cache in case we need to restore it for + emitting an uncompressed block. */ + memcpy(s->saved_dist_cache_, s->dist_cache_, sizeof(s->saved_dist_cache_)); + *output = &storage[0]; + *out_size = storage_ix >> 3; + return BROTLI_TRUE; + } +} + +/* Dumps remaining output bits and metadata header to |header|. + Returns number of produced bytes. + REQUIRED: |header| should be 8-byte aligned and at least 16 bytes long. + REQUIRED: |block_size| <= (1 << 24). */ +static size_t WriteMetadataHeader( + BrotliEncoderState* s, const size_t block_size, uint8_t* header) { + size_t storage_ix; + storage_ix = s->last_bytes_bits_; + header[0] = (uint8_t)s->last_bytes_; + header[1] = (uint8_t)(s->last_bytes_ >> 8); + s->last_bytes_ = 0; + s->last_bytes_bits_ = 0; + + BrotliWriteBits(1, 0, &storage_ix, header); + BrotliWriteBits(2, 3, &storage_ix, header); + BrotliWriteBits(1, 0, &storage_ix, header); + if (block_size == 0) { + BrotliWriteBits(2, 0, &storage_ix, header); + } else { + uint32_t nbits = (block_size == 1) ? 1 : + (Log2FloorNonZero((uint32_t)block_size - 1) + 1); + uint32_t nbytes = (nbits + 7) / 8; + BrotliWriteBits(2, nbytes, &storage_ix, header); + BrotliWriteBits(8 * nbytes, block_size - 1, &storage_ix, header); + } + return (storage_ix + 7u) >> 3; +} + +size_t BrotliEncoderMaxCompressedSize(size_t input_size) { + /* [window bits / empty metadata] + N * [uncompressed] + [last empty] */ + size_t num_large_blocks = input_size >> 14; + size_t overhead = 2 + (4 * num_large_blocks) + 3 + 1; + size_t result = input_size + overhead; + if (input_size == 0) return 2; + return (result < input_size) ? 0 : result; +} + +/* Wraps data to uncompressed brotli stream with minimal window size. + |output| should point at region with at least BrotliEncoderMaxCompressedSize + addressable bytes. + Returns the length of stream. */ +static size_t MakeUncompressedStream( + const uint8_t* input, size_t input_size, uint8_t* output) { + size_t size = input_size; + size_t result = 0; + size_t offset = 0; + if (input_size == 0) { + output[0] = 6; + return 1; + } + output[result++] = 0x21; /* window bits = 10, is_last = false */ + output[result++] = 0x03; /* empty metadata, padding */ + while (size > 0) { + uint32_t nibbles = 0; + uint32_t chunk_size; + uint32_t bits; + chunk_size = (size > (1u << 24)) ? (1u << 24) : (uint32_t)size; + if (chunk_size > (1u << 16)) nibbles = (chunk_size > (1u << 20)) ? 2 : 1; + bits = + (nibbles << 1) | ((chunk_size - 1) << 3) | (1u << (19 + 4 * nibbles)); + output[result++] = (uint8_t)bits; + output[result++] = (uint8_t)(bits >> 8); + output[result++] = (uint8_t)(bits >> 16); + if (nibbles == 2) output[result++] = (uint8_t)(bits >> 24); + memcpy(&output[result], &input[offset], chunk_size); + result += chunk_size; + offset += chunk_size; + size -= chunk_size; + } + output[result++] = 3; + return result; +} + +BROTLI_BOOL BrotliEncoderCompress( + int quality, int lgwin, BrotliEncoderMode mode, size_t input_size, + const uint8_t input_buffer[BROTLI_ARRAY_PARAM(input_size)], + size_t* encoded_size, + uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(*encoded_size)]) { + BrotliEncoderState* s; + size_t out_size = *encoded_size; + const uint8_t* input_start = input_buffer; + uint8_t* output_start = encoded_buffer; + size_t max_out_size = BrotliEncoderMaxCompressedSize(input_size); + if (out_size == 0) { + /* Output buffer needs at least one byte. */ + return BROTLI_FALSE; + } + if (input_size == 0) { + /* Handle the special case of empty input. */ + *encoded_size = 1; + *encoded_buffer = 6; + return BROTLI_TRUE; + } + + s = BrotliEncoderCreateInstance(0, 0, 0); + if (!s) { + return BROTLI_FALSE; + } else { + size_t available_in = input_size; + const uint8_t* next_in = input_buffer; + size_t available_out = *encoded_size; + uint8_t* next_out = encoded_buffer; + size_t total_out = 0; + BROTLI_BOOL result = BROTLI_FALSE; + /* TODO(eustas): check that parameters are sane. */ + BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, (uint32_t)quality); + BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, (uint32_t)lgwin); + BrotliEncoderSetParameter(s, BROTLI_PARAM_MODE, (uint32_t)mode); + BrotliEncoderSetParameter(s, BROTLI_PARAM_SIZE_HINT, (uint32_t)input_size); + if (lgwin > BROTLI_MAX_WINDOW_BITS) { + BrotliEncoderSetParameter(s, BROTLI_PARAM_LARGE_WINDOW, BROTLI_TRUE); + } + result = BrotliEncoderCompressStream(s, BROTLI_OPERATION_FINISH, + &available_in, &next_in, &available_out, &next_out, &total_out); + if (!BrotliEncoderIsFinished(s)) result = 0; + *encoded_size = total_out; + BrotliEncoderDestroyInstance(s); + if (!result || (max_out_size && *encoded_size > max_out_size)) { + goto fallback; + } + return BROTLI_TRUE; + } +fallback: + *encoded_size = 0; + if (!max_out_size) return BROTLI_FALSE; + if (out_size >= max_out_size) { + *encoded_size = + MakeUncompressedStream(input_start, input_size, output_start); + return BROTLI_TRUE; + } + return BROTLI_FALSE; +} + +static void InjectBytePaddingBlock(BrotliEncoderState* s) { + uint32_t seal = s->last_bytes_; + size_t seal_bits = s->last_bytes_bits_; + uint8_t* destination; + s->last_bytes_ = 0; + s->last_bytes_bits_ = 0; + /* is_last = 0, data_nibbles = 11, reserved = 0, meta_nibbles = 00 */ + seal |= 0x6u << seal_bits; + seal_bits += 6; + /* If we have already created storage, then append to it. + Storage is valid until next block is being compressed. */ + if (s->next_out_) { + destination = s->next_out_ + s->available_out_; + } else { + destination = s->tiny_buf_.u8; + s->next_out_ = destination; + } + destination[0] = (uint8_t)seal; + if (seal_bits > 8) destination[1] = (uint8_t)(seal >> 8); + if (seal_bits > 16) destination[2] = (uint8_t)(seal >> 16); + s->available_out_ += (seal_bits + 7) >> 3; +} + +/* Fills the |total_out|, if it is not NULL. */ +static void SetTotalOut(BrotliEncoderState* s, size_t* total_out) { + if (total_out) { + /* Saturating conversion uint64_t -> size_t */ + size_t result = (size_t)-1; + if (s->total_out_ < result) { + result = (size_t)s->total_out_; + } + *total_out = result; + } +} + +/* Injects padding bits or pushes compressed data to output. + Returns false if nothing is done. */ +static BROTLI_BOOL InjectFlushOrPushOutput(BrotliEncoderState* s, + size_t* available_out, uint8_t** next_out, size_t* total_out) { + if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED && + s->last_bytes_bits_ != 0) { + InjectBytePaddingBlock(s); + return BROTLI_TRUE; + } + + if (s->available_out_ != 0 && *available_out != 0) { + size_t copy_output_size = + BROTLI_MIN(size_t, s->available_out_, *available_out); + memcpy(*next_out, s->next_out_, copy_output_size); + *next_out += copy_output_size; + *available_out -= copy_output_size; + s->next_out_ += copy_output_size; + s->available_out_ -= copy_output_size; + s->total_out_ += copy_output_size; + SetTotalOut(s, total_out); + return BROTLI_TRUE; + } + + return BROTLI_FALSE; +} + +static void CheckFlushComplete(BrotliEncoderState* s) { + if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED && + s->available_out_ == 0) { + s->stream_state_ = BROTLI_STREAM_PROCESSING; + s->next_out_ = 0; + } +} + +static BROTLI_BOOL BrotliEncoderCompressStreamFast( + BrotliEncoderState* s, BrotliEncoderOperation op, size_t* available_in, + const uint8_t** next_in, size_t* available_out, uint8_t** next_out, + size_t* total_out) { + const size_t block_size_limit = (size_t)1 << s->params.lgwin; + const size_t buf_size = BROTLI_MIN(size_t, kCompressFragmentTwoPassBlockSize, + BROTLI_MIN(size_t, *available_in, block_size_limit)); + uint32_t* tmp_command_buf = NULL; + uint32_t* command_buf = NULL; + uint8_t* tmp_literal_buf = NULL; + uint8_t* literal_buf = NULL; + MemoryManager* m = &s->memory_manager_; + if (s->params.quality != FAST_ONE_PASS_COMPRESSION_QUALITY && + s->params.quality != FAST_TWO_PASS_COMPRESSION_QUALITY) { + return BROTLI_FALSE; + } + if (s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) { + if (!s->command_buf_ && buf_size == kCompressFragmentTwoPassBlockSize) { + s->command_buf_ = + BROTLI_ALLOC(m, uint32_t, kCompressFragmentTwoPassBlockSize); + s->literal_buf_ = + BROTLI_ALLOC(m, uint8_t, kCompressFragmentTwoPassBlockSize); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(s->command_buf_) || + BROTLI_IS_NULL(s->literal_buf_)) { + return BROTLI_FALSE; + } + } + if (s->command_buf_) { + command_buf = s->command_buf_; + literal_buf = s->literal_buf_; + } else { + tmp_command_buf = BROTLI_ALLOC(m, uint32_t, buf_size); + tmp_literal_buf = BROTLI_ALLOC(m, uint8_t, buf_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tmp_command_buf) || + BROTLI_IS_NULL(tmp_literal_buf)) { + return BROTLI_FALSE; + } + command_buf = tmp_command_buf; + literal_buf = tmp_literal_buf; + } + } + + while (BROTLI_TRUE) { + if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) { + continue; + } + + /* Compress block only when internal output buffer is empty, stream is not + finished, there is no pending flush request, and there is either + additional input or pending operation. */ + if (s->available_out_ == 0 && + s->stream_state_ == BROTLI_STREAM_PROCESSING && + (*available_in != 0 || op != BROTLI_OPERATION_PROCESS)) { + size_t block_size = BROTLI_MIN(size_t, block_size_limit, *available_in); + BROTLI_BOOL is_last = + (*available_in == block_size) && (op == BROTLI_OPERATION_FINISH); + BROTLI_BOOL force_flush = + (*available_in == block_size) && (op == BROTLI_OPERATION_FLUSH); + size_t max_out_size = 2 * block_size + 503; + BROTLI_BOOL inplace = BROTLI_TRUE; + uint8_t* storage = NULL; + size_t storage_ix = s->last_bytes_bits_; + size_t table_size; + int* table; + + if (force_flush && block_size == 0) { + s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED; + continue; + } + if (max_out_size <= *available_out) { + storage = *next_out; + } else { + inplace = BROTLI_FALSE; + storage = GetBrotliStorage(s, max_out_size); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + } + storage[0] = (uint8_t)s->last_bytes_; + storage[1] = (uint8_t)(s->last_bytes_ >> 8); + table = GetHashTable(s, s->params.quality, block_size, &table_size); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + + if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) { + BrotliCompressFragmentFast(s->one_pass_arena_, *next_in, block_size, + is_last, table, table_size, &storage_ix, storage); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + } else { + BrotliCompressFragmentTwoPass(s->two_pass_arena_, *next_in, block_size, + is_last, command_buf, literal_buf, table, table_size, + &storage_ix, storage); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + } + if (block_size != 0) { + *next_in += block_size; + *available_in -= block_size; + s->total_in_ += block_size; + } + if (inplace) { + size_t out_bytes = storage_ix >> 3; + BROTLI_DCHECK(out_bytes <= *available_out); + BROTLI_DCHECK((storage_ix & 7) == 0 || out_bytes < *available_out); + *next_out += out_bytes; + *available_out -= out_bytes; + s->total_out_ += out_bytes; + SetTotalOut(s, total_out); + } else { + size_t out_bytes = storage_ix >> 3; + s->next_out_ = storage; + s->available_out_ = out_bytes; + } + s->last_bytes_ = (uint16_t)(storage[storage_ix >> 3]); + s->last_bytes_bits_ = storage_ix & 7u; + + if (force_flush) s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED; + if (is_last) s->stream_state_ = BROTLI_STREAM_FINISHED; + continue; + } + break; + } + BROTLI_FREE(m, tmp_command_buf); + BROTLI_FREE(m, tmp_literal_buf); + CheckFlushComplete(s); + return BROTLI_TRUE; +} + +static BROTLI_BOOL ProcessMetadata( + BrotliEncoderState* s, size_t* available_in, const uint8_t** next_in, + size_t* available_out, uint8_t** next_out, size_t* total_out) { + if (*available_in > (1u << 24)) return BROTLI_FALSE; + /* Switch to metadata block workflow, if required. */ + if (s->stream_state_ == BROTLI_STREAM_PROCESSING) { + s->remaining_metadata_bytes_ = (uint32_t)*available_in; + s->stream_state_ = BROTLI_STREAM_METADATA_HEAD; + } + if (s->stream_state_ != BROTLI_STREAM_METADATA_HEAD && + s->stream_state_ != BROTLI_STREAM_METADATA_BODY) { + return BROTLI_FALSE; + } + + while (BROTLI_TRUE) { + if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) { + continue; + } + if (s->available_out_ != 0) break; + + if (s->input_pos_ != s->last_flush_pos_) { + BROTLI_BOOL result = EncodeData(s, BROTLI_FALSE, BROTLI_TRUE, + &s->available_out_, &s->next_out_); + if (!result) return BROTLI_FALSE; + continue; + } + + if (s->stream_state_ == BROTLI_STREAM_METADATA_HEAD) { + s->next_out_ = s->tiny_buf_.u8; + s->available_out_ = + WriteMetadataHeader(s, s->remaining_metadata_bytes_, s->next_out_); + s->stream_state_ = BROTLI_STREAM_METADATA_BODY; + continue; + } else { + /* Exit workflow only when there is no more input and no more output. + Otherwise client may continue producing empty metadata blocks. */ + if (s->remaining_metadata_bytes_ == 0) { + s->remaining_metadata_bytes_ = BROTLI_UINT32_MAX; + s->stream_state_ = BROTLI_STREAM_PROCESSING; + break; + } + if (*available_out) { + /* Directly copy input to output. */ + uint32_t copy = (uint32_t)BROTLI_MIN( + size_t, s->remaining_metadata_bytes_, *available_out); + memcpy(*next_out, *next_in, copy); + *next_in += copy; + *available_in -= copy; + s->total_in_ += copy; /* not actually data input, though */ + s->remaining_metadata_bytes_ -= copy; + *next_out += copy; + *available_out -= copy; + } else { + /* This guarantees progress in "TakeOutput" workflow. */ + uint32_t copy = BROTLI_MIN(uint32_t, s->remaining_metadata_bytes_, 16); + s->next_out_ = s->tiny_buf_.u8; + memcpy(s->next_out_, *next_in, copy); + *next_in += copy; + *available_in -= copy; + s->total_in_ += copy; /* not actually data input, though */ + s->remaining_metadata_bytes_ -= copy; + s->available_out_ = copy; + } + continue; + } + } + + return BROTLI_TRUE; +} + +static void UpdateSizeHint(BrotliEncoderState* s, size_t available_in) { + if (s->params.size_hint == 0) { + uint64_t delta = UnprocessedInputSize(s); + uint64_t tail = available_in; + uint32_t limit = 1u << 30; + uint32_t total; + if ((delta >= limit) || (tail >= limit) || ((delta + tail) >= limit)) { + total = limit; + } else { + total = (uint32_t)(delta + tail); + } + s->params.size_hint = total; + } +} + +BROTLI_BOOL BrotliEncoderCompressStream( + BrotliEncoderState* s, BrotliEncoderOperation op, size_t* available_in, + const uint8_t** next_in, size_t* available_out, uint8_t** next_out, + size_t* total_out) { + if (!EnsureInitialized(s)) return BROTLI_FALSE; + + /* Unfinished metadata block; check requirements. */ + if (s->remaining_metadata_bytes_ != BROTLI_UINT32_MAX) { + if (*available_in != s->remaining_metadata_bytes_) return BROTLI_FALSE; + if (op != BROTLI_OPERATION_EMIT_METADATA) return BROTLI_FALSE; + } + + if (op == BROTLI_OPERATION_EMIT_METADATA) { + UpdateSizeHint(s, 0); /* First data metablock might be emitted here. */ + return ProcessMetadata( + s, available_in, next_in, available_out, next_out, total_out); + } + + if (s->stream_state_ == BROTLI_STREAM_METADATA_HEAD || + s->stream_state_ == BROTLI_STREAM_METADATA_BODY) { + return BROTLI_FALSE; + } + + if (s->stream_state_ != BROTLI_STREAM_PROCESSING && *available_in != 0) { + return BROTLI_FALSE; + } + if (s->params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY || + s->params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) { + return BrotliEncoderCompressStreamFast(s, op, available_in, next_in, + available_out, next_out, total_out); + } + while (BROTLI_TRUE) { + size_t remaining_block_size = RemainingInputBlockSize(s); + /* Shorten input to flint size. */ + if (s->flint_ >= 0 && remaining_block_size > (size_t)s->flint_) { + remaining_block_size = (size_t)s->flint_; + } + + if (remaining_block_size != 0 && *available_in != 0) { + size_t copy_input_size = + BROTLI_MIN(size_t, remaining_block_size, *available_in); + CopyInputToRingBuffer(s, copy_input_size, *next_in); + *next_in += copy_input_size; + *available_in -= copy_input_size; + s->total_in_ += copy_input_size; + if (s->flint_ > 0) s->flint_ = (int8_t)(s->flint_ - (int)copy_input_size); + continue; + } + + if (InjectFlushOrPushOutput(s, available_out, next_out, total_out)) { + /* Exit the "emit flint" workflow. */ + if (s->flint_ == BROTLI_FLINT_WAITING_FOR_FLUSHING) { + CheckFlushComplete(s); + if (s->stream_state_ == BROTLI_STREAM_PROCESSING) { + s->flint_ = BROTLI_FLINT_DONE; + } + } + continue; + } + + /* Compress data only when internal output buffer is empty, stream is not + finished and there is no pending flush request. */ + if (s->available_out_ == 0 && + s->stream_state_ == BROTLI_STREAM_PROCESSING) { + if (remaining_block_size == 0 || op != BROTLI_OPERATION_PROCESS) { + BROTLI_BOOL is_last = TO_BROTLI_BOOL( + (*available_in == 0) && op == BROTLI_OPERATION_FINISH); + BROTLI_BOOL force_flush = TO_BROTLI_BOOL( + (*available_in == 0) && op == BROTLI_OPERATION_FLUSH); + BROTLI_BOOL result; + /* Force emitting (uncompressed) piece containing flint. */ + if (!is_last && s->flint_ == 0) { + s->flint_ = BROTLI_FLINT_WAITING_FOR_FLUSHING; + force_flush = BROTLI_TRUE; + } + UpdateSizeHint(s, *available_in); + result = EncodeData(s, is_last, force_flush, + &s->available_out_, &s->next_out_); + if (!result) return BROTLI_FALSE; + if (force_flush) s->stream_state_ = BROTLI_STREAM_FLUSH_REQUESTED; + if (is_last) s->stream_state_ = BROTLI_STREAM_FINISHED; + continue; + } + } + break; + } + CheckFlushComplete(s); + return BROTLI_TRUE; +} + +BROTLI_BOOL BrotliEncoderIsFinished(BrotliEncoderState* s) { + return TO_BROTLI_BOOL(s->stream_state_ == BROTLI_STREAM_FINISHED && + !BrotliEncoderHasMoreOutput(s)); +} + +BROTLI_BOOL BrotliEncoderHasMoreOutput(BrotliEncoderState* s) { + return TO_BROTLI_BOOL(s->available_out_ != 0); +} + +const uint8_t* BrotliEncoderTakeOutput(BrotliEncoderState* s, size_t* size) { + size_t consumed_size = s->available_out_; + uint8_t* result = s->next_out_; + if (*size) { + consumed_size = BROTLI_MIN(size_t, *size, s->available_out_); + } + if (consumed_size) { + s->next_out_ += consumed_size; + s->available_out_ -= consumed_size; + s->total_out_ += consumed_size; + CheckFlushComplete(s); + *size = consumed_size; + } else { + *size = 0; + result = 0; + } + return result; +} + +uint32_t BrotliEncoderVersion(void) { + return BROTLI_VERSION; +} + +BrotliEncoderPreparedDictionary* BrotliEncoderPrepareDictionary( + BrotliSharedDictionaryType type, size_t size, + const uint8_t data[BROTLI_ARRAY_PARAM(size)], int quality, + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + ManagedDictionary* managed_dictionary = NULL; + BROTLI_BOOL type_is_known = BROTLI_FALSE; + type_is_known |= (type == BROTLI_SHARED_DICTIONARY_RAW); +#if defined(BROTLI_EXPERIMENTAL) + type_is_known |= (type == BROTLI_SHARED_DICTIONARY_SERIALIZED); +#endif /* BROTLI_EXPERIMENTAL */ + if (!type_is_known) { + return NULL; + } + managed_dictionary = + BrotliCreateManagedDictionary(alloc_func, free_func, opaque); + if (managed_dictionary == NULL) { + return NULL; + } + if (type == BROTLI_SHARED_DICTIONARY_RAW) { + managed_dictionary->dictionary = (uint32_t*)CreatePreparedDictionary( + &managed_dictionary->memory_manager_, data, size); + } +#if defined(BROTLI_EXPERIMENTAL) + if (type == BROTLI_SHARED_DICTIONARY_SERIALIZED) { + SharedEncoderDictionary* dict = (SharedEncoderDictionary*)BrotliAllocate( + &managed_dictionary->memory_manager_, sizeof(SharedEncoderDictionary)); + managed_dictionary->dictionary = (uint32_t*)dict; + if (dict != NULL) { + BROTLI_BOOL ok = BrotliInitCustomSharedEncoderDictionary( + &managed_dictionary->memory_manager_, data, size, quality, dict); + if (!ok) { + BrotliFree(&managed_dictionary->memory_manager_, dict); + managed_dictionary->dictionary = NULL; + } + } + } +#else /* BROTLI_EXPERIMENTAL */ + (void)quality; +#endif /* BROTLI_EXPERIMENTAL */ + if (managed_dictionary->dictionary == NULL) { + BrotliDestroyManagedDictionary(managed_dictionary); + return NULL; + } + return (BrotliEncoderPreparedDictionary*)managed_dictionary; +} + +void BROTLI_COLD BrotliEncoderDestroyPreparedDictionary( + BrotliEncoderPreparedDictionary* dictionary) { + ManagedDictionary* dict = (ManagedDictionary*)dictionary; + if (!dictionary) return; + /* First field of dictionary structs. */ + /* Only managed dictionaries are eligible for destruction by this method. */ + if (dict->magic != kManagedDictionaryMagic) { + return; + } + if (dict->dictionary == NULL) { + /* This should never ever happen. */ + } else if (*dict->dictionary == kLeanPreparedDictionaryMagic) { + DestroyPreparedDictionary( + &dict->memory_manager_, (PreparedDictionary*)dict->dictionary); + } else if (*dict->dictionary == kSharedDictionaryMagic) { + BrotliCleanupSharedEncoderDictionary(&dict->memory_manager_, + (SharedEncoderDictionary*)dict->dictionary); + BrotliFree(&dict->memory_manager_, dict->dictionary); + } else { + /* There is also kPreparedDictionaryMagic, but such instances should be + * constructed and destroyed by different means. */ + } + dict->dictionary = NULL; + BrotliDestroyManagedDictionary(dict); +} + +BROTLI_BOOL BROTLI_COLD BrotliEncoderAttachPreparedDictionary( + BrotliEncoderState* state, + const BrotliEncoderPreparedDictionary* dictionary) { + /* First field of dictionary structs */ + const BrotliEncoderPreparedDictionary* dict = dictionary; + uint32_t magic = *((const uint32_t*)dict); + SharedEncoderDictionary* current = NULL; + if (magic == kManagedDictionaryMagic) { + /* Unwrap managed dictionary. */ + ManagedDictionary* managed_dictionary = (ManagedDictionary*)dict; + magic = *managed_dictionary->dictionary; + dict = (BrotliEncoderPreparedDictionary*)managed_dictionary->dictionary; + } + current = &state->params.dictionary; + if (magic == kPreparedDictionaryMagic || + magic == kLeanPreparedDictionaryMagic) { + const PreparedDictionary* prepared = (const PreparedDictionary*)dict; + if (!AttachPreparedDictionary(¤t->compound, prepared)) { + return BROTLI_FALSE; + } + } else if (magic == kSharedDictionaryMagic) { + const SharedEncoderDictionary* attached = + (const SharedEncoderDictionary*)dict; + BROTLI_BOOL was_default = !current->contextual.context_based && + current->contextual.num_dictionaries == 1 && + current->contextual.dict[0]->hash_table_words == + kStaticDictionaryHashWords && + current->contextual.dict[0]->hash_table_lengths == + kStaticDictionaryHashLengths; + BROTLI_BOOL new_default = !attached->contextual.context_based && + attached->contextual.num_dictionaries == 1 && + attached->contextual.dict[0]->hash_table_words == + kStaticDictionaryHashWords && + attached->contextual.dict[0]->hash_table_lengths == + kStaticDictionaryHashLengths; + size_t i; + if (state->is_initialized_) return BROTLI_FALSE; + current->max_quality = + BROTLI_MIN(int, current->max_quality, attached->max_quality); + for (i = 0; i < attached->compound.num_chunks; i++) { + if (!AttachPreparedDictionary(¤t->compound, + attached->compound.chunks[i])) { + return BROTLI_FALSE; + } + } + if (!new_default) { + if (!was_default) return BROTLI_FALSE; + /* Copy by value, but then set num_instances_ to 0 because their memory + is managed by attached, not by current */ + current->contextual = attached->contextual; + current->contextual.num_instances_ = 0; + } + } else { + return BROTLI_FALSE; + } + return BROTLI_TRUE; +} + +size_t BROTLI_COLD BrotliEncoderEstimatePeakMemoryUsage(int quality, int lgwin, + size_t input_size) { + BrotliEncoderParams params; + size_t memory_manager_slots = BROTLI_ENCODER_MEMORY_MANAGER_SLOTS; + size_t memory_manager_size = memory_manager_slots * sizeof(void*); + BrotliEncoderInitParams(¶ms); + params.quality = quality; + params.lgwin = lgwin; + params.size_hint = input_size; + params.large_window = lgwin > BROTLI_MAX_WINDOW_BITS; + SanitizeParams(¶ms); + params.lgblock = ComputeLgBlock(¶ms); + ChooseHasher(¶ms, ¶ms.hasher); + if (params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY || + params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY) { + size_t state_size = sizeof(BrotliEncoderState); + size_t block_size = BROTLI_MIN(size_t, input_size, ((size_t)1ul << params.lgwin)); + size_t hash_table_size = + HashTableSize(MaxHashTableSize(params.quality), block_size); + size_t hash_size = + (hash_table_size < (1u << 10)) ? 0 : sizeof(int) * hash_table_size; + size_t cmdbuf_size = params.quality == FAST_TWO_PASS_COMPRESSION_QUALITY ? + 5 * BROTLI_MIN(size_t, block_size, 1ul << 17) : 0; + if (params.quality == FAST_ONE_PASS_COMPRESSION_QUALITY) { + state_size += sizeof(BrotliOnePassArena); + } else { + state_size += sizeof(BrotliTwoPassArena); + } + return hash_size + cmdbuf_size + state_size; + } else { + size_t short_ringbuffer_size = (size_t)1 << params.lgblock; + int ringbuffer_bits = ComputeRbBits(¶ms); + size_t ringbuffer_size = input_size < short_ringbuffer_size ? + input_size : ((size_t)1u << ringbuffer_bits) + short_ringbuffer_size; + size_t hash_size[4] = {0}; + size_t metablock_size = + BROTLI_MIN(size_t, input_size, MaxMetablockSize(¶ms)); + size_t inputblock_size = + BROTLI_MIN(size_t, input_size, (size_t)1 << params.lgblock); + size_t cmdbuf_size = metablock_size * 2 + inputblock_size * 6; + size_t outbuf_size = metablock_size * 2 + 503; + size_t histogram_size = 0; + HasherSize(¶ms, BROTLI_TRUE, input_size, hash_size); + if (params.quality < MIN_QUALITY_FOR_BLOCK_SPLIT) { + cmdbuf_size = BROTLI_MIN(size_t, cmdbuf_size, + MAX_NUM_DELAYED_SYMBOLS * sizeof(Command) + inputblock_size * 12); + } + if (params.quality >= MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING) { + /* Only a very rough estimation, based on enwik8. */ + histogram_size = 200 << 20; + } else if (params.quality >= MIN_QUALITY_FOR_BLOCK_SPLIT) { + size_t literal_histograms = + BROTLI_MIN(size_t, metablock_size / 6144, 256); + size_t command_histograms = + BROTLI_MIN(size_t, metablock_size / 6144, 256); + size_t distance_histograms = + BROTLI_MIN(size_t, metablock_size / 6144, 256); + histogram_size = literal_histograms * sizeof(HistogramLiteral) + + command_histograms * sizeof(HistogramCommand) + + distance_histograms * sizeof(HistogramDistance); + } + return (memory_manager_size + ringbuffer_size + + hash_size[0] + hash_size[1] + hash_size[2] + hash_size[3] + + cmdbuf_size + + outbuf_size + + histogram_size); + } +} +size_t BROTLI_COLD BrotliEncoderGetPreparedDictionarySize( + const BrotliEncoderPreparedDictionary* prepared_dictionary) { + /* First field of dictionary structs */ + const BrotliEncoderPreparedDictionary* prepared = prepared_dictionary; + uint32_t magic = *((const uint32_t*)prepared); + size_t overhead = 0; + if (magic == kManagedDictionaryMagic) { + const ManagedDictionary* managed = (const ManagedDictionary*)prepared; + overhead = sizeof(ManagedDictionary); + magic = *managed->dictionary; + prepared = (const BrotliEncoderPreparedDictionary*)managed->dictionary; + } + + if (magic == kPreparedDictionaryMagic) { + const PreparedDictionary* dictionary = + (const PreparedDictionary*)prepared; + /* Keep in sync with step 3 of CreatePreparedDictionary */ + return sizeof(PreparedDictionary) + dictionary->source_size + + (sizeof(uint32_t) << dictionary->slot_bits) + + (sizeof(uint16_t) << dictionary->bucket_bits) + + (sizeof(uint32_t) * dictionary->num_items) + overhead; + } else if (magic == kLeanPreparedDictionaryMagic) { + const PreparedDictionary* dictionary = + (const PreparedDictionary*)prepared; + /* Keep in sync with step 3 of CreatePreparedDictionary */ + return sizeof(PreparedDictionary) + sizeof(uint8_t*) + + (sizeof(uint32_t) << dictionary->slot_bits) + + (sizeof(uint16_t) << dictionary->bucket_bits) + + (sizeof(uint32_t) * dictionary->num_items) + overhead; + } else if (magic == kSharedDictionaryMagic) { + const SharedEncoderDictionary* dictionary = + (const SharedEncoderDictionary*)prepared; + const CompoundDictionary* compound = &dictionary->compound; + const ContextualEncoderDictionary* contextual = &dictionary->contextual; + size_t result = sizeof(*dictionary); + size_t i; + size_t num_instances; + const BrotliEncoderDictionary* instances; + for (i = 0; i < compound->num_prepared_instances_; i++) { + size_t size = BrotliEncoderGetPreparedDictionarySize( + (const BrotliEncoderPreparedDictionary*) + compound->prepared_instances_[i]); + if (!size) return 0; /* error */ + result += size; + } + if (contextual->context_based) { + num_instances = contextual->num_instances_; + instances = contextual->instances_; + result += sizeof(*instances) * num_instances; + } else { + num_instances = 1; + instances = &contextual->instance_; + } + for (i = 0; i < num_instances; i++) { + const BrotliEncoderDictionary* dict = &instances[i]; + result += dict->trie.pool_capacity * sizeof(BrotliTrieNode); + if (dict->hash_table_data_words_) { + result += sizeof(kStaticDictionaryHashWords); + } + if (dict->hash_table_data_lengths_) { + result += sizeof(kStaticDictionaryHashLengths); + } + if (dict->buckets_data_) { + result += sizeof(*dict->buckets_data_) * dict->buckets_alloc_size_; + } + if (dict->dict_words_data_) { + result += sizeof(*dict->dict_words) * dict->dict_words_alloc_size_; + } + if (dict->words_instance_) { + result += sizeof(*dict->words_instance_); + /* data_size not added here: it is never allocated by the + SharedEncoderDictionary, instead it always points to the file + already loaded in memory. So if the caller wants to include + this memory as well, add the size of the loaded dictionary + file to this. */ + } + } + return result + overhead; + } + return 0; /* error */ +} + +#if defined(BROTLI_TEST) +size_t BrotliMakeUncompressedStreamForTest(const uint8_t*, size_t, uint8_t*); +size_t BrotliMakeUncompressedStreamForTest( + const uint8_t* input, size_t input_size, uint8_t* output) { + return MakeUncompressedStream(input, input_size, output); +} +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/encoder_dict.c b/packages/runtime/vendor/brotli/c/enc/encoder_dict.c new file mode 100644 index 000000000..f75ee5984 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/encoder_dict.c @@ -0,0 +1,642 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "encoder_dict.h" + +#include "../common/dictionary.h" +#include "../common/platform.h" +#include +#include "../common/shared_dictionary_internal.h" +#include "../common/transform.h" +#include +#include "compound_dictionary.h" +#include "dictionary_hash.h" +#include "hash_base.h" +#include "hash.h" +#include "memory.h" +#include "quality.h" +#include "static_dict_lut.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define NUM_HASH_BITS 15u +#define NUM_HASH_BUCKETS (1u << NUM_HASH_BITS) + +static void BrotliTrieInit(BrotliTrie* trie) { + trie->pool_capacity = 0; + trie->pool_size = 0; + trie->pool = 0; + + /* Set up the root node */ + trie->root.single = 0; + trie->root.len_ = 0; + trie->root.idx_ = 0; + trie->root.sub = 0; +} + +static void BrotliTrieFree(MemoryManager* m, BrotliTrie* trie) { + BrotliFree(m, trie->pool); +} + +/* Initializes to RFC 7932 static dictionary / transforms. */ +static void InitEncoderDictionary(BrotliEncoderDictionary* dict) { + dict->words = BrotliGetDictionary(); + dict->num_transforms = (uint32_t)BrotliGetTransforms()->num_transforms; + + dict->hash_table_words = kStaticDictionaryHashWords; + dict->hash_table_lengths = kStaticDictionaryHashLengths; + dict->buckets = kStaticDictionaryBuckets; + dict->dict_words = kStaticDictionaryWords; + + dict->cutoffTransformsCount = kCutoffTransformsCount; + dict->cutoffTransforms = kCutoffTransforms; + + dict->parent = 0; + + dict->hash_table_data_words_ = 0; + dict->hash_table_data_lengths_ = 0; + dict->buckets_alloc_size_ = 0; + dict->buckets_data_ = 0; + dict->dict_words_alloc_size_ = 0; + dict->dict_words_data_ = 0; + dict->words_instance_ = 0; + dict->has_words_heavy = BROTLI_FALSE; + BrotliTrieInit(&dict->trie); +} + +static void BrotliDestroyEncoderDictionary(MemoryManager* m, + BrotliEncoderDictionary* dict) { + BrotliFree(m, dict->hash_table_data_words_); + BrotliFree(m, dict->hash_table_data_lengths_); + BrotliFree(m, dict->buckets_data_); + BrotliFree(m, dict->dict_words_data_); + BrotliFree(m, dict->words_instance_); + BrotliTrieFree(m, &dict->trie); +} + +#if defined(BROTLI_EXPERIMENTAL) +/* Word length must be at least 4 bytes */ +static uint32_t Hash(const uint8_t* data, int bits) { + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - bits); +} + +/* Theoretical max possible word size after transform */ +#define kTransformedBufferSize \ + (256 + 256 + SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH) + +/* To be safe buffer must have at least kTransformedBufferSize */ +static void TransformedDictionaryWord(uint32_t word_idx, int len, int transform, + const BrotliTransforms* transforms, + const BrotliEncoderDictionary* dict, + uint8_t* buffer, size_t* size) { + const uint8_t* dict_word = &dict->words->data[ + dict->words->offsets_by_length[len] + (uint32_t)len * word_idx]; + *size = (size_t)BrotliTransformDictionaryWord(buffer, dict_word, len, + transforms, transform); +} + +static DictWord MakeDictWord(uint8_t len, uint8_t transform, uint16_t idx) { + DictWord result; + result.len = len; + result.transform = transform; + result.idx = idx; + return result; +} + +static uint32_t BrotliTrieAlloc(MemoryManager* m, size_t num, BrotliTrie* trie, + BrotliTrieNode** keep) { + uint32_t result; + uint32_t keep_index = 0; + if (keep && *keep != &trie->root) { + /* Optional node to keep, since address may change after re-allocating */ + keep_index = (uint32_t)(*keep - trie->pool); + } + if (trie->pool_size == 0) { + /* Have a placeholder node in the front. We do not want the result to be 0, + it must be at least 1, 0 represents "null pointer" */ + trie->pool_size = 1; + } + BROTLI_ENSURE_CAPACITY(m, BrotliTrieNode, trie->pool, trie->pool_capacity, + trie->pool_size + num); + if (BROTLI_IS_OOM(m)) return 0; + /* Init the new nodes to empty */ + memset(trie->pool + trie->pool_size, 0, sizeof(*trie->pool) * num); + result = (uint32_t)trie->pool_size; + trie->pool_size += num; + if (keep && *keep != &trie->root) { + *keep = trie->pool + keep_index; + } + return result; +} + +/** + * len and idx: payload for last node + * word, size: the string + * index: position in the string + */ +static BROTLI_BOOL BrotliTrieNodeAdd(MemoryManager* m, uint8_t len, + uint32_t idx, const uint8_t* word, size_t size, int index, + BrotliTrieNode* node, BrotliTrie* trie) { + BrotliTrieNode* child = 0; + uint8_t c; + if ((size_t)index == size) { + if (!node->len_ || idx < node->idx_) { + node->len_ = len; + node->idx_ = idx; + } + return BROTLI_TRUE; + } + c = word[index]; + if (node->single && c != node->c) { + BrotliTrieNode old = trie->pool[node->sub]; + uint32_t new_nodes = BrotliTrieAlloc(m, 32, trie, &node); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + node->single = 0; + node->sub = new_nodes; + trie->pool[node->sub + (node->c >> 4)].sub = new_nodes + 16; + trie->pool[trie->pool[node->sub + (node->c >> 4)].sub + (node->c & 15)] = + old; + } + if (!node->sub) { + uint32_t new_node = BrotliTrieAlloc(m, 1, trie, &node); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + node->single = 1; + node->c = c; + node->sub = new_node; + } + if (node->single) { + child = &trie->pool[node->sub]; + } else { + if (!trie->pool[node->sub + (c >> 4)].sub) { + uint32_t new_nodes = BrotliTrieAlloc(m, 16, trie, &node); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + trie->pool[node->sub + (c >> 4)].sub = new_nodes; + } + child = &trie->pool[trie->pool[node->sub + (c >> 4)].sub + (c & 15)]; + } + return BrotliTrieNodeAdd(m, len, idx, word, size, index + 1, child, trie); +} + +static BROTLI_BOOL BrotliTrieAdd(MemoryManager* m, uint8_t len, uint32_t idx, + const uint8_t* word, size_t size, BrotliTrie* trie) { + return BrotliTrieNodeAdd(m, len, idx, word, size, 0, &trie->root, trie); +} + +const BrotliTrieNode* BrotliTrieSub(const BrotliTrie* trie, + const BrotliTrieNode* node, uint8_t c) { + BrotliTrieNode* temp_node; + if (node->single) { + if (node->c == c) return &trie->pool[node->sub]; + return 0; + } + if (!node->sub) return 0; + temp_node = &trie->pool[node->sub + (c >> 4)]; + if (!temp_node->sub) return 0; + return &trie->pool[temp_node->sub + (c & 15)]; +} + +static const BrotliTrieNode* BrotliTrieFind(const BrotliTrie* trie, + const uint8_t* word, size_t size) { + const BrotliTrieNode* node = &trie->root; + size_t i; + for (i = 0; i < size; i++) { + node = BrotliTrieSub(trie, node, word[i]); + if (!node) return 0; + } + return node; +} + +static BROTLI_BOOL BuildDictionaryLut(MemoryManager* m, + const BrotliTransforms* transforms, + BrotliEncoderDictionary* dict) { + uint32_t i; + DictWord* dict_words; + uint16_t* buckets; + DictWord** words_by_hash; + size_t* words_by_hash_size; + size_t* words_by_hash_capacity; + BrotliTrie dedup; + uint8_t word[kTransformedBufferSize]; + size_t word_size; + size_t total = 0; + uint8_t l; + uint16_t idx; + + BrotliTrieInit(&dedup); + + words_by_hash = (DictWord**)BrotliAllocate(m, + sizeof(*words_by_hash) * NUM_HASH_BUCKETS); + words_by_hash_size = (size_t*)BrotliAllocate(m, + sizeof(*words_by_hash_size) * NUM_HASH_BUCKETS); + words_by_hash_capacity = (size_t*)BrotliAllocate(m, + sizeof(*words_by_hash_capacity) * NUM_HASH_BUCKETS); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + memset(words_by_hash, 0, sizeof(*words_by_hash) * NUM_HASH_BUCKETS); + memset(words_by_hash_size, 0, sizeof(*words_by_hash_size) * NUM_HASH_BUCKETS); + memset(words_by_hash_capacity, 0, + sizeof(*words_by_hash_capacity) * NUM_HASH_BUCKETS); + + if (transforms->num_transforms > 0) { + for (l = SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH; + l <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH; ++l) { + uint16_t n = dict->words->size_bits_by_length[l] ? + (uint16_t)(1 << dict->words->size_bits_by_length[l]) : 0u; + for (idx = 0; idx < n; ++idx) { + uint32_t key; + /* First transform (usually identity) */ + TransformedDictionaryWord(idx, l, 0, transforms, dict, word, + &word_size); + /* Cannot hash words smaller than 4 bytes */ + if (word_size < 4) { + /* Break instead of continue, all next words of this length will have + same length after transform */ + break; + } + if (!BrotliTrieAdd(m, 0, idx, word, word_size, &dedup)) { + return BROTLI_FALSE; + } + key = Hash(word, NUM_HASH_BITS); + BROTLI_ENSURE_CAPACITY_APPEND(m, DictWord, words_by_hash[key], + words_by_hash_capacity[key], words_by_hash_size[key], + MakeDictWord(l, 0, idx)); + ++total; + } + } + } + + /* These LUT transforms only supported if no custom transforms. This is + ok, we will use the heavy trie instead. */ + if (transforms == BrotliGetTransforms()) { + for (l = SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH; + l <= SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH; ++l) { + uint16_t n = dict->words->size_bits_by_length[l] ? + (uint16_t)(1 << dict->words->size_bits_by_length[l]) : 0u; + for (idx = 0; idx < n; ++idx) { + int k; + BROTLI_BOOL is_ascii = BROTLI_TRUE; + size_t offset = dict->words->offsets_by_length[l] + (size_t)l * idx; + const uint8_t* data = &dict->words->data[offset]; + for (k = 0; k < l; ++k) { + if (data[k] >= 128) is_ascii = BROTLI_FALSE; + } + if (data[0] < 128) { + int transform = 9; /* {empty, uppercase first, empty} */ + uint32_t ix = idx + (uint32_t)transform * n; + const BrotliTrieNode* it; + TransformedDictionaryWord(idx, l, transform, transforms, + dict, word, &word_size); + it = BrotliTrieFind(&dedup, word, word_size); + if (!it || it->idx_ > ix) { + uint32_t key = Hash(word, NUM_HASH_BITS); + if (!BrotliTrieAdd(m, 0, ix, word, word_size, &dedup)) { + return BROTLI_FALSE; + } + BROTLI_ENSURE_CAPACITY_APPEND(m, DictWord, words_by_hash[key], + words_by_hash_capacity[key], words_by_hash_size[key], + MakeDictWord(l, BROTLI_TRANSFORM_UPPERCASE_FIRST, idx)); + ++total; + } + } + if (is_ascii) { + int transform = 44; /* {empty, uppercase all, empty} */ + uint32_t ix = idx + (uint32_t)transform * n; + const BrotliTrieNode* it; + TransformedDictionaryWord(idx, l, transform, transforms, + dict, word, &word_size); + it = BrotliTrieFind(&dedup, word, word_size); + if (!it || it->idx_ > ix) { + uint32_t key = Hash(word, NUM_HASH_BITS); + if (!BrotliTrieAdd(m, 0, ix, word, word_size, &dedup)) { + return BROTLI_FALSE; + } + BROTLI_ENSURE_CAPACITY_APPEND(m, DictWord, words_by_hash[key], + words_by_hash_capacity[key], words_by_hash_size[key], + MakeDictWord(l, BROTLI_TRANSFORM_UPPERCASE_ALL, idx)); + ++total; + } + } + } + } + } + + dict_words = (DictWord*)BrotliAllocate(m, + sizeof(*dict->dict_words) * (total + 1)); + buckets = (uint16_t*)BrotliAllocate(m, + sizeof(*dict->buckets) * NUM_HASH_BUCKETS); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + dict->dict_words_alloc_size_ = total + 1; + dict->dict_words = dict->dict_words_data_ = dict_words; + dict->buckets_alloc_size_ = NUM_HASH_BUCKETS; + dict->buckets = dict->buckets_data_ = buckets; + + /* Unused; makes offsets start from 1. */ + dict_words[0] = MakeDictWord(0, 0, 0); + total = 1; + for (i = 0; i < NUM_HASH_BUCKETS; ++i) { + size_t num_words = words_by_hash_size[i]; + if (num_words > 0) { + buckets[i] = (uint16_t)(total); + memcpy(&dict_words[total], &words_by_hash[i][0], + sizeof(dict_words[0]) * num_words); + total += num_words; + dict_words[total - 1].len |= 0x80; + } else { + buckets[i] = 0; + } + } + + for (i = 0; i < NUM_HASH_BUCKETS; ++i) { + BrotliFree(m, words_by_hash[i]); + } + BrotliFree(m, words_by_hash); + BrotliFree(m, words_by_hash_size); + BrotliFree(m, words_by_hash_capacity); + BrotliTrieFree(m, &dedup); + + return BROTLI_TRUE; +} + +static void BuildDictionaryHashTable(uint16_t* hash_table_words, + uint8_t* hash_table_lengths, const BrotliDictionary* dict) { + int j, len; + /* The order of the loops is such that in case of collision, words with + shorter length are preferred, and in case of same length, words with + smaller index. There is only a single word per bucket. */ + /* TODO(lode): consider adding optional user-supplied frequency_map to use + for preferred words instead, this can make the encoder better for + quality 9 and below without affecting the decoder */ + memset(hash_table_words, 0, sizeof(kStaticDictionaryHashWords)); + memset(hash_table_lengths, 0, sizeof(kStaticDictionaryHashLengths)); + for (len = SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH; + len >= SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH; --len) { + const size_t num_words = dict->size_bits_by_length[len] ? + (1u << dict->size_bits_by_length[len]) : 0; + for (j = (int)num_words - 1; j >= 0; --j) { + size_t offset = dict->offsets_by_length[len] + + (size_t)len * (size_t)j; + const uint8_t* word = &dict->data[offset]; + const uint32_t key = Hash(word, 14); + int idx = (int)(key << 1) + (len < 8 ? 1 : 0); + BROTLI_DCHECK(idx < (int)NUM_HASH_BUCKETS); + hash_table_words[idx] = (uint16_t)j; + hash_table_lengths[idx] = (uint8_t)len; + } + } +} + +static BROTLI_BOOL GenerateWordsHeavy(MemoryManager* m, + const BrotliTransforms* transforms, + BrotliEncoderDictionary* dict) { + int i, j, l; + for (j = (int)transforms->num_transforms - 1; j >= 0 ; --j) { + for (l = 0; l < 32; l++) { + int num = (int)((1u << dict->words->size_bits_by_length[l]) & ~1u); + for (i = 0; i < num; i++) { + uint8_t transformed[kTransformedBufferSize]; + size_t size; + TransformedDictionaryWord( + (uint32_t)i, l, j, transforms, dict, transformed, &size); + if (size < 4) continue; + if (!BrotliTrieAdd(m, (uint8_t)l, (uint32_t)(i + num * j), + transformed, size, &dict->trie)) { + return BROTLI_FALSE; + } + } + } + } + return BROTLI_TRUE; +} + +/* Computes cutoffTransformsCount (in count) and cutoffTransforms (in data) for + the custom transforms, where possible within the limits of the + cutoffTransforms encoding. The fast encoder uses this to do fast lookup for + transforms that remove the N last characters (OmitLast). */ +static void ComputeCutoffTransforms( + const BrotliTransforms* transforms, + uint32_t* count, uint64_t* data) { + int i; + /* The encoding in a 64-bit integer of transform N in the data is: (N << 2) + + ((cutoffTransforms >> (N * 6)) & 0x3F), so for example the identity + transform code must be 0-63, for N=1 the transform code must be 4-67, ..., + for N=9 it must be 36-99. + TODO(lode): consider a simple flexible uint8_t[10] instead of the uint64_t + for the cutoff transforms, so that shared dictionaries can have the + OmitLast transforms anywhere without loss. */ + *count = 0; + *data = 0; + for (i = 0; i < BROTLI_TRANSFORMS_MAX_CUT_OFF + 1; i++) { + int idx = transforms->cutOffTransforms[i]; + if (idx == -1) break; /* Not found */ + if (idx < (i << 2)) break; /* Too small for the encoding */ + if (idx >= (i << 2) + 64) break; /* Too large for the encoding */ + (*count)++; + *data |= (uint64_t)(((uint64_t)idx - + ((uint64_t)i << 2u)) << ((uint64_t)i * 6u)); + } +} + +static BROTLI_BOOL ComputeDictionary(MemoryManager* m, int quality, + const BrotliTransforms* transforms, + BrotliEncoderDictionary* current) { + int default_words = current->words == BrotliGetDictionary(); + int default_transforms = transforms == BrotliGetTransforms(); + + if (default_words && default_transforms) { + /* hashes are already set to Brotli defaults */ + return BROTLI_TRUE; + } + + current->hash_table_data_words_ = (uint16_t*)BrotliAllocate( + m, sizeof(kStaticDictionaryHashWords)); + current->hash_table_data_lengths_ = (uint8_t*)BrotliAllocate( + m, sizeof(kStaticDictionaryHashLengths)); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + current->hash_table_words = current->hash_table_data_words_; + current->hash_table_lengths = current->hash_table_data_lengths_; + + BuildDictionaryHashTable(current->hash_table_data_words_, + current->hash_table_data_lengths_, current->words); + + ComputeCutoffTransforms(transforms, + ¤t->cutoffTransformsCount, ¤t->cutoffTransforms); + + /* Only compute the data for slow encoder if the requested quality is high + enough to need it */ + if (quality >= ZOPFLIFICATION_QUALITY) { + if (!BuildDictionaryLut(m, transforms, current)) return BROTLI_FALSE; + + /* For the built-in Brotli transforms, there is a hard-coded function to + handle all transforms, but for custom transforms, we use the following + large hammer instead */ + current->has_words_heavy = !default_transforms; + if (current->has_words_heavy) { + if (!GenerateWordsHeavy(m, transforms, current)) return BROTLI_FALSE; + } + } + + return BROTLI_TRUE; +} +#endif /* BROTLI_EXPERIMENTAL */ + +void BrotliInitSharedEncoderDictionary(SharedEncoderDictionary* dict) { + dict->magic = kSharedDictionaryMagic; + + dict->compound.num_chunks = 0; + dict->compound.total_size = 0; + dict->compound.chunk_offsets[0] = 0; + dict->compound.num_prepared_instances_ = 0; + + dict->contextual.context_based = 0; + dict->contextual.num_dictionaries = 1; + dict->contextual.instances_ = 0; + dict->contextual.num_instances_ = 1; /* The instance_ field */ + dict->contextual.dict[0] = &dict->contextual.instance_; + InitEncoderDictionary(&dict->contextual.instance_); + dict->contextual.instance_.parent = &dict->contextual; + + dict->max_quality = BROTLI_MAX_QUALITY; +} + +#if defined(BROTLI_EXPERIMENTAL) +/* TODO(eustas): make sure that tooling will warn user if not all the cutoff + transforms are available (for low-quality encoder). */ +static BROTLI_BOOL InitCustomSharedEncoderDictionary( + MemoryManager* m, const BrotliSharedDictionary* decoded_dict, + int quality, SharedEncoderDictionary* dict) { + ContextualEncoderDictionary* contextual; + CompoundDictionary* compound; + BrotliEncoderDictionary* instances; + int i; + BrotliInitSharedEncoderDictionary(dict); + + contextual = &dict->contextual; + compound = &dict->compound; + + for (i = 0; i < (int)decoded_dict->num_prefix; i++) { + PreparedDictionary* prepared = CreatePreparedDictionary(m, + decoded_dict->prefix[i], decoded_dict->prefix_size[i]); + AttachPreparedDictionary(compound, prepared); + /* remember for cleanup */ + compound->prepared_instances_[ + compound->num_prepared_instances_++] = prepared; + } + + dict->max_quality = quality; + contextual->context_based = decoded_dict->context_based; + if (decoded_dict->context_based) { + memcpy(contextual->context_map, decoded_dict->context_map, + SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS); + } + + contextual->num_dictionaries = decoded_dict->num_dictionaries; + contextual->num_instances_ = decoded_dict->num_dictionaries; + if (contextual->num_instances_ == 1) { + instances = &contextual->instance_; + } else { + contextual->instances_ = (BrotliEncoderDictionary*) + BrotliAllocate(m, sizeof(*contextual->instances_) * + contextual->num_instances_); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + instances = contextual->instances_; + } + for (i = 0; i < (int)contextual->num_instances_; i++) { + BrotliEncoderDictionary* current = &instances[i]; + InitEncoderDictionary(current); + current->parent = &dict->contextual; + if (decoded_dict->words[i] == BrotliGetDictionary()) { + current->words = BrotliGetDictionary(); + } else { + current->words_instance_ = (BrotliDictionary*)BrotliAllocate( + m, sizeof(BrotliDictionary)); + if (BROTLI_IS_OOM(m)) return BROTLI_FALSE; + *current->words_instance_ = *decoded_dict->words[i]; + current->words = current->words_instance_; + } + current->num_transforms = + (uint32_t)decoded_dict->transforms[i]->num_transforms; + if (!ComputeDictionary( + m, quality, decoded_dict->transforms[i], current)) { + return BROTLI_FALSE; + } + + contextual->dict[i] = current; + } + + return BROTLI_TRUE; /* success */ +} + +BROTLI_BOOL BrotliInitCustomSharedEncoderDictionary( + MemoryManager* m, const uint8_t* encoded_dict, size_t size, + int quality, SharedEncoderDictionary* dict) { + BROTLI_BOOL success = BROTLI_FALSE; + BrotliSharedDictionary* decoded_dict = BrotliSharedDictionaryCreateInstance( + m->alloc_func, m->free_func, m->opaque); + if (!decoded_dict) { /* OOM */ + return BROTLI_FALSE; + } + success = BrotliSharedDictionaryAttach( + decoded_dict, BROTLI_SHARED_DICTIONARY_SERIALIZED, size, encoded_dict); + if (success) { + success = InitCustomSharedEncoderDictionary(m, + decoded_dict, quality, dict); + } + BrotliSharedDictionaryDestroyInstance(decoded_dict); + return success; +} +#endif /* BROTLI_EXPERIMENTAL */ + +void BrotliCleanupSharedEncoderDictionary(MemoryManager* m, + SharedEncoderDictionary* dict) { + size_t i; + for (i = 0; i < dict->compound.num_prepared_instances_; i++) { + DestroyPreparedDictionary(m, + (PreparedDictionary*)dict->compound.prepared_instances_[i]); + } + if (dict->contextual.num_instances_ == 1) { + BrotliDestroyEncoderDictionary(m, &dict->contextual.instance_); + } else if (dict->contextual.num_instances_ > 1) { + for (i = 0; i < dict->contextual.num_instances_; i++) { + BrotliDestroyEncoderDictionary(m, &dict->contextual.instances_[i]); + } + BrotliFree(m, dict->contextual.instances_); + } +} + +ManagedDictionary* BrotliCreateManagedDictionary( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + ManagedDictionary* result = (ManagedDictionary*)BrotliBootstrapAlloc( + sizeof(ManagedDictionary), alloc_func, free_func, opaque); + if (result == NULL) return NULL; + + result->magic = kManagedDictionaryMagic; + BrotliInitMemoryManager( + &result->memory_manager_, alloc_func, free_func, opaque); + result->dictionary = NULL; + + return result; +} + +void BrotliDestroyManagedDictionary(ManagedDictionary* dictionary) { + if (!dictionary) return; + BrotliBootstrapFree(dictionary, &dictionary->memory_manager_); +} + +/* Escalate internal functions visibility; for testing purposes only. */ +#if defined(BROTLI_TEST) +void BrotliInitEncoderDictionaryForTest(BrotliEncoderDictionary*); +void BrotliInitEncoderDictionaryForTest(BrotliEncoderDictionary* d) { + InitEncoderDictionary(d); +} +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/encoder_dict.h b/packages/runtime/vendor/brotli/c/enc/encoder_dict.h new file mode 100644 index 000000000..76f037977 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/encoder_dict.h @@ -0,0 +1,155 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#ifndef BROTLI_ENC_ENCODER_DICT_H_ +#define BROTLI_ENC_ENCODER_DICT_H_ + +#include "../common/dictionary.h" +#include +#include "../common/platform.h" +#include "compound_dictionary.h" +#include "memory.h" +#include "static_dict_lut.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* +Dictionary hierarchy for Encoder: +-SharedEncoderDictionary +--CompoundDictionary +---PreparedDictionary [up to 15x] + = prefix dictionary with precomputed hashes +--ContextualEncoderDictionary +---BrotliEncoderDictionary [up to 64x] + = for each context, precomputed static dictionary with words + transforms + +Dictionary hierarchy from common: similar, but without precomputed hashes +-BrotliSharedDictionary +--BrotliDictionary [up to 64x] +--BrotliTransforms [up to 64x] +--const uint8_t* prefix [up to 15x]: compound dictionaries +*/ + +typedef struct BrotliTrieNode { + uint8_t single; /* if 1, sub is a single node for c instead of 256 */ + uint8_t c; + uint8_t len_; /* untransformed length */ + uint32_t idx_; /* word index + num words * transform index */ + uint32_t sub; /* index of sub node(s) in the pool */ +} BrotliTrieNode; + +typedef struct BrotliTrie { + BrotliTrieNode* pool; + size_t pool_capacity; + size_t pool_size; + BrotliTrieNode root; +} BrotliTrie; + +#if defined(BROTLI_EXPERIMENTAL) +BROTLI_INTERNAL const BrotliTrieNode* BrotliTrieSub(const BrotliTrie* trie, + const BrotliTrieNode* node, uint8_t c); +#endif /* BROTLI_EXPERIMENTAL */ + +/* Dictionary data (words and transforms) for 1 possible context */ +typedef struct BrotliEncoderDictionary { + const BrotliDictionary* words; + uint32_t num_transforms; + + /* cut off for fast encoder */ + uint32_t cutoffTransformsCount; + uint64_t cutoffTransforms; + + /* from dictionary_hash.h, for fast encoder */ + const uint16_t* hash_table_words; + const uint8_t* hash_table_lengths; + + /* from static_dict_lut.h, for slow encoder */ + const uint16_t* buckets; + const DictWord* dict_words; + /* Heavy version, for use by slow encoder when there are custom transforms. + Contains every possible transformed dictionary word in a trie. It encodes + about as fast as the non-heavy encoder but consumes a lot of memory and + takes time to build. */ + BrotliTrie trie; + BROTLI_BOOL has_words_heavy; + + /* Reference to other dictionaries. */ + const struct ContextualEncoderDictionary* parent; + + /* Allocated memory, used only when not using the Brotli defaults */ + uint16_t* hash_table_data_words_; + uint8_t* hash_table_data_lengths_; + size_t buckets_alloc_size_; + uint16_t* buckets_data_; + size_t dict_words_alloc_size_; + DictWord* dict_words_data_; + BrotliDictionary* words_instance_; +} BrotliEncoderDictionary; + +/* Dictionary data for all 64 contexts */ +typedef struct ContextualEncoderDictionary { + BROTLI_BOOL context_based; + uint8_t num_dictionaries; + uint8_t context_map[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS]; + const BrotliEncoderDictionary* dict[SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS]; + + /* If num_instances_ is 1, instance_ is used, else dynamic allocation with + instances_ is used. */ + size_t num_instances_; + BrotliEncoderDictionary instance_; + BrotliEncoderDictionary* instances_; +} ContextualEncoderDictionary; + +typedef struct SharedEncoderDictionary { + /* Magic value to distinguish this struct from PreparedDictionary for + certain external usages. */ + uint32_t magic; + + /* LZ77 prefix, compound dictionary */ + CompoundDictionary compound; + + /* Custom static dictionary (optionally context-based) */ + ContextualEncoderDictionary contextual; + + /* The maximum quality the dictionary was computed for */ + int max_quality; +} SharedEncoderDictionary; + +typedef struct ManagedDictionary { + uint32_t magic; + MemoryManager memory_manager_; + uint32_t* dictionary; +} ManagedDictionary; + +/* Initializes to the brotli built-in dictionary */ +BROTLI_INTERNAL void BrotliInitSharedEncoderDictionary( + SharedEncoderDictionary* dict); + +#if defined(BROTLI_EXPERIMENTAL) +/* Initializes to shared dictionary that will be parsed from + encoded_dict. Requires that you keep the encoded_dict buffer + around, parts of data will point to it. */ +BROTLI_INTERNAL BROTLI_BOOL BrotliInitCustomSharedEncoderDictionary( + MemoryManager* m, const uint8_t* encoded_dict, size_t size, + int quality, SharedEncoderDictionary* dict); +#endif /* BROTLI_EXPERIMENTAL */ + +BROTLI_INTERNAL void BrotliCleanupSharedEncoderDictionary( + MemoryManager* m, SharedEncoderDictionary* dict); + +BROTLI_INTERNAL ManagedDictionary* BrotliCreateManagedDictionary( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); + +BROTLI_INTERNAL void BrotliDestroyManagedDictionary( + ManagedDictionary* dictionary); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_ENCODER_DICT_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/entropy_encode.c b/packages/runtime/vendor/brotli/c/enc/entropy_encode.c new file mode 100644 index 000000000..1b4eab97f --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/entropy_encode.c @@ -0,0 +1,501 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Entropy encoding (Huffman) utilities. */ + +#include "entropy_encode.h" + +#include "../common/constants.h" +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +const BROTLI_MODEL("small") size_t kBrotliShellGaps[] = {132, 57, 23, 10, 4, 1}; + +BROTLI_BOOL BrotliSetDepth( + int p0, HuffmanTree* pool, uint8_t* depth, int max_depth) { + int stack[16]; + int level = 0; + int p = p0; + BROTLI_DCHECK(max_depth <= 15); + stack[0] = -1; + while (BROTLI_TRUE) { + if (pool[p].index_left_ >= 0) { + level++; + if (level > max_depth) return BROTLI_FALSE; + stack[level] = pool[p].index_right_or_value_; + p = pool[p].index_left_; + continue; + } else { + depth[pool[p].index_right_or_value_] = (uint8_t)level; + } + while (level >= 0 && stack[level] == -1) level--; + if (level < 0) return BROTLI_TRUE; + p = stack[level]; + stack[level] = -1; + } +} + +/* Sort the root nodes, least popular first. */ +static BROTLI_INLINE BROTLI_BOOL SortHuffmanTree( + const HuffmanTree* v0, const HuffmanTree* v1) { + if (v0->total_count_ != v1->total_count_) { + return TO_BROTLI_BOOL(v0->total_count_ < v1->total_count_); + } + return TO_BROTLI_BOOL(v0->index_right_or_value_ > v1->index_right_or_value_); +} + +/* This function will create a Huffman tree. + + The catch here is that the tree cannot be arbitrarily deep. + Brotli specifies a maximum depth of 15 bits for "code trees" + and 7 bits for "code length code trees." + + count_limit is the value that is to be faked as the minimum value + and this minimum value is raised until the tree matches the + maximum length requirement. + + This algorithm is not of excellent performance for very long data blocks, + especially when population counts are longer than 2**tree_limit, but + we are not planning to use this with extremely long blocks. + + See http://en.wikipedia.org/wiki/Huffman_coding */ +void BrotliCreateHuffmanTree(const uint32_t* data, + const size_t length, + const int tree_limit, + HuffmanTree* tree, + uint8_t* depth) { + uint32_t count_limit; + HuffmanTree sentinel; + InitHuffmanTree(&sentinel, BROTLI_UINT32_MAX, -1, -1); + /* For block sizes below 64 kB, we never need to do a second iteration + of this loop. Probably all of our block sizes will be smaller than + that, so this loop is mostly of academic interest. If we actually + would need this, we would be better off with the Katajainen algorithm. */ + for (count_limit = 1; ; count_limit *= 2) { + size_t n = 0; + size_t i; + size_t j; + size_t k; + for (i = length; i != 0;) { + --i; + if (data[i]) { + const uint32_t count = BROTLI_MAX(uint32_t, data[i], count_limit); + InitHuffmanTree(&tree[n++], count, -1, (int16_t)i); + } + } + + if (n == 1) { + depth[tree[0].index_right_or_value_] = 1; /* Only one element. */ + break; + } + + SortHuffmanTreeItems(tree, n, SortHuffmanTree); + + /* The nodes are: + [0, n): the sorted leaf nodes that we start with. + [n]: we add a sentinel here. + [n + 1, 2n): new parent nodes are added here, starting from + (n+1). These are naturally in ascending order. + [2n]: we add a sentinel at the end as well. + There will be (2n+1) elements at the end. */ + tree[n] = sentinel; + tree[n + 1] = sentinel; + + i = 0; /* Points to the next leaf node. */ + j = n + 1; /* Points to the next non-leaf node. */ + for (k = n - 1; k != 0; --k) { + size_t left, right; + if (tree[i].total_count_ <= tree[j].total_count_) { + left = i; + ++i; + } else { + left = j; + ++j; + } + if (tree[i].total_count_ <= tree[j].total_count_) { + right = i; + ++i; + } else { + right = j; + ++j; + } + + { + /* The sentinel node becomes the parent node. */ + size_t j_end = 2 * n - k; + tree[j_end].total_count_ = + tree[left].total_count_ + tree[right].total_count_; + tree[j_end].index_left_ = (int16_t)left; + tree[j_end].index_right_or_value_ = (int16_t)right; + + /* Add back the last sentinel node. */ + tree[j_end + 1] = sentinel; + } + } + if (BrotliSetDepth((int)(2 * n - 1), &tree[0], depth, tree_limit)) { + /* We need to pack the Huffman tree in tree_limit bits. If this was not + successful, add fake entities to the lowest values and retry. */ + break; + } + } +} + +static void Reverse(uint8_t* v, size_t start, size_t end) { + --end; + while (start < end) { + uint8_t tmp = v[start]; + v[start] = v[end]; + v[end] = tmp; + ++start; + --end; + } +} + +static void BrotliWriteHuffmanTreeRepetitions( + const uint8_t previous_value, + const uint8_t value, + size_t repetitions, + size_t* tree_size, + uint8_t* tree, + uint8_t* extra_bits_data) { + BROTLI_DCHECK(repetitions > 0); + if (previous_value != value) { + tree[*tree_size] = value; + extra_bits_data[*tree_size] = 0; + ++(*tree_size); + --repetitions; + } + if (repetitions == 7) { + tree[*tree_size] = value; + extra_bits_data[*tree_size] = 0; + ++(*tree_size); + --repetitions; + } + if (repetitions < 3) { + size_t i; + for (i = 0; i < repetitions; ++i) { + tree[*tree_size] = value; + extra_bits_data[*tree_size] = 0; + ++(*tree_size); + } + } else { + size_t start = *tree_size; + repetitions -= 3; + while (BROTLI_TRUE) { + tree[*tree_size] = BROTLI_REPEAT_PREVIOUS_CODE_LENGTH; + extra_bits_data[*tree_size] = repetitions & 0x3; + ++(*tree_size); + repetitions >>= 2; + if (repetitions == 0) { + break; + } + --repetitions; + } + Reverse(tree, start, *tree_size); + Reverse(extra_bits_data, start, *tree_size); + } +} + +static void BrotliWriteHuffmanTreeRepetitionsZeros( + size_t repetitions, + size_t* tree_size, + uint8_t* tree, + uint8_t* extra_bits_data) { + if (repetitions == 11) { + tree[*tree_size] = 0; + extra_bits_data[*tree_size] = 0; + ++(*tree_size); + --repetitions; + } + if (repetitions < 3) { + size_t i; + for (i = 0; i < repetitions; ++i) { + tree[*tree_size] = 0; + extra_bits_data[*tree_size] = 0; + ++(*tree_size); + } + } else { + size_t start = *tree_size; + repetitions -= 3; + while (BROTLI_TRUE) { + tree[*tree_size] = BROTLI_REPEAT_ZERO_CODE_LENGTH; + extra_bits_data[*tree_size] = repetitions & 0x7; + ++(*tree_size); + repetitions >>= 3; + if (repetitions == 0) { + break; + } + --repetitions; + } + Reverse(tree, start, *tree_size); + Reverse(extra_bits_data, start, *tree_size); + } +} + +void BrotliOptimizeHuffmanCountsForRle(size_t length, uint32_t* counts, + uint8_t* good_for_rle) { + size_t nonzero_count = 0; + size_t stride; + size_t limit; + size_t sum; + const size_t streak_limit = 1240; + /* Let's make the Huffman code more compatible with RLE encoding. */ + size_t i; + for (i = 0; i < length; i++) { + if (counts[i]) { + ++nonzero_count; + } + } + if (nonzero_count < 16) { + return; + } + while (length != 0 && counts[length - 1] == 0) { + --length; + } + if (length == 0) { + return; /* All zeros. */ + } + /* Now counts[0..length - 1] does not have trailing zeros. */ + { + size_t nonzeros = 0; + uint32_t smallest_nonzero = 1 << 30; + for (i = 0; i < length; ++i) { + if (counts[i] != 0) { + ++nonzeros; + if (smallest_nonzero > counts[i]) { + smallest_nonzero = counts[i]; + } + } + } + if (nonzeros < 5) { + /* Small histogram will model it well. */ + return; + } + if (smallest_nonzero < 4) { + size_t zeros = length - nonzeros; + if (zeros < 6) { + for (i = 1; i < length - 1; ++i) { + if (counts[i - 1] != 0 && counts[i] == 0 && counts[i + 1] != 0) { + counts[i] = 1; + } + } + } + } + if (nonzeros < 28) { + return; + } + } + /* 2) Let's mark all population counts that already can be encoded + with an RLE code. */ + memset(good_for_rle, 0, length); + { + /* Let's not spoil any of the existing good RLE codes. + Mark any seq of 0's that is longer as 5 as a good_for_rle. + Mark any seq of non-0's that is longer as 7 as a good_for_rle. */ + uint32_t symbol = counts[0]; + size_t step = 0; + for (i = 0; i <= length; ++i) { + if (i == length || counts[i] != symbol) { + if ((symbol == 0 && step >= 5) || + (symbol != 0 && step >= 7)) { + size_t k; + for (k = 0; k < step; ++k) { + good_for_rle[i - k - 1] = 1; + } + } + step = 1; + if (i != length) { + symbol = counts[i]; + } + } else { + ++step; + } + } + } + /* 3) Let's replace those population counts that lead to more RLE codes. + Math here is in 24.8 fixed point representation. */ + stride = 0; + limit = 256 * (counts[0] + counts[1] + counts[2]) / 3 + 420; + sum = 0; + for (i = 0; i <= length; ++i) { + if (i == length || good_for_rle[i] || + (i != 0 && good_for_rle[i - 1]) || + (256 * counts[i] - limit + streak_limit) >= 2 * streak_limit) { + if (stride >= 4 || (stride >= 3 && sum == 0)) { + size_t k; + /* The stride must end, collapse what we have, if we have enough (4). */ + size_t count = (sum + stride / 2) / stride; + if (count == 0) { + count = 1; + } + if (sum == 0) { + /* Don't make an all zeros stride to be upgraded to ones. */ + count = 0; + } + for (k = 0; k < stride; ++k) { + /* We don't want to change value at counts[i], + that is already belonging to the next stride. Thus - 1. */ + counts[i - k - 1] = (uint32_t)count; + } + } + stride = 0; + sum = 0; + if (i < length - 2) { + /* All interesting strides have a count of at least 4, */ + /* at least when non-zeros. */ + limit = 256 * (counts[i] + counts[i + 1] + counts[i + 2]) / 3 + 420; + } else if (i < length) { + limit = 256 * counts[i]; + } else { + limit = 0; + } + } + ++stride; + if (i != length) { + sum += counts[i]; + if (stride >= 4) { + limit = (256 * sum + stride / 2) / stride; + } + if (stride == 4) { + limit += 120; + } + } + } +} + +static void DecideOverRleUse(const uint8_t* depth, const size_t length, + BROTLI_BOOL* use_rle_for_non_zero, + BROTLI_BOOL* use_rle_for_zero) { + size_t total_reps_zero = 0; + size_t total_reps_non_zero = 0; + size_t count_reps_zero = 1; + size_t count_reps_non_zero = 1; + size_t i; + for (i = 0; i < length;) { + const uint8_t value = depth[i]; + size_t reps = 1; + size_t k; + for (k = i + 1; k < length && depth[k] == value; ++k) { + ++reps; + } + if (reps >= 3 && value == 0) { + total_reps_zero += reps; + ++count_reps_zero; + } + if (reps >= 4 && value != 0) { + total_reps_non_zero += reps; + ++count_reps_non_zero; + } + i += reps; + } + *use_rle_for_non_zero = + TO_BROTLI_BOOL(total_reps_non_zero > count_reps_non_zero * 2); + *use_rle_for_zero = TO_BROTLI_BOOL(total_reps_zero > count_reps_zero * 2); +} + +void BrotliWriteHuffmanTree(const uint8_t* depth, + size_t length, + size_t* tree_size, + uint8_t* tree, + uint8_t* extra_bits_data) { + uint8_t previous_value = BROTLI_INITIAL_REPEATED_CODE_LENGTH; + size_t i; + BROTLI_BOOL use_rle_for_non_zero = BROTLI_FALSE; + BROTLI_BOOL use_rle_for_zero = BROTLI_FALSE; + + /* Throw away trailing zeros. */ + size_t new_length = length; + for (i = 0; i < length; ++i) { + if (depth[length - i - 1] == 0) { + --new_length; + } else { + break; + } + } + + /* First gather statistics on if it is a good idea to do RLE. */ + if (length > 50) { + /* Find RLE coding for longer codes. + Shorter codes seem not to benefit from RLE. */ + DecideOverRleUse(depth, new_length, + &use_rle_for_non_zero, &use_rle_for_zero); + } + + /* Actual RLE coding. */ + for (i = 0; i < new_length;) { + const uint8_t value = depth[i]; + size_t reps = 1; + if ((value != 0 && use_rle_for_non_zero) || + (value == 0 && use_rle_for_zero)) { + size_t k; + for (k = i + 1; k < new_length && depth[k] == value; ++k) { + ++reps; + } + } + if (value == 0) { + BrotliWriteHuffmanTreeRepetitionsZeros( + reps, tree_size, tree, extra_bits_data); + } else { + BrotliWriteHuffmanTreeRepetitions(previous_value, + value, reps, tree_size, + tree, extra_bits_data); + previous_value = value; + } + i += reps; + } +} + +static uint16_t BrotliReverseBits(size_t num_bits, uint16_t bits) { + static const size_t BROTLI_MODEL("small") kLut[16] = + { /* Pre-reversed 4-bit values. */ + 0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E, + 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F + }; + size_t retval = kLut[bits & 0x0F]; + size_t i; + for (i = 4; i < num_bits; i += 4) { + retval <<= 4; + bits = (uint16_t)(bits >> 4); + retval |= kLut[bits & 0x0F]; + } + retval >>= ((0 - num_bits) & 0x03); + return (uint16_t)retval; +} + +/* 0..15 are values for bits */ +#define MAX_HUFFMAN_BITS 16 + +void BrotliConvertBitDepthsToSymbols(const uint8_t* depth, + size_t len, + uint16_t* bits) { + /* In Brotli, all bit depths are [1..15] + 0 bit depth means that the symbol does not exist. */ + uint16_t bl_count[MAX_HUFFMAN_BITS] = { 0 }; + uint16_t next_code[MAX_HUFFMAN_BITS]; + size_t i; + int code = 0; + for (i = 0; i < len; ++i) { + ++bl_count[depth[i]]; + } + bl_count[0] = 0; + next_code[0] = 0; + for (i = 1; i < MAX_HUFFMAN_BITS; ++i) { + code = (code + bl_count[i - 1]) << 1; + next_code[i] = (uint16_t)code; + } + for (i = 0; i < len; ++i) { + if (depth[i]) { + bits[i] = BrotliReverseBits(depth[i], next_code[depth[i]]++); + } + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/entropy_encode.h b/packages/runtime/vendor/brotli/c/enc/entropy_encode.h new file mode 100644 index 000000000..0470c16e0 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/entropy_encode.h @@ -0,0 +1,121 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Entropy encoding (Huffman) utilities. */ + +#ifndef BROTLI_ENC_ENTROPY_ENCODE_H_ +#define BROTLI_ENC_ENTROPY_ENCODE_H_ + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* A node of a Huffman tree. */ +typedef struct HuffmanTree { + uint32_t total_count_; + int16_t index_left_; + int16_t index_right_or_value_; +} HuffmanTree; + +static BROTLI_INLINE void InitHuffmanTree(HuffmanTree* self, uint32_t count, + int16_t left, int16_t right) { + self->total_count_ = count; + self->index_left_ = left; + self->index_right_or_value_ = right; +} + +/* Returns 1 is assignment of depths succeeded, otherwise 0. */ +BROTLI_INTERNAL BROTLI_BOOL BrotliSetDepth( + int p, HuffmanTree* pool, uint8_t* depth, int max_depth); + +/* This function will create a Huffman tree. + + The (data,length) contains the population counts. + The tree_limit is the maximum bit depth of the Huffman codes. + + The depth contains the tree, i.e., how many bits are used for + the symbol. + + The actual Huffman tree is constructed in the tree[] array, which has to + be at least 2 * length + 1 long. + + See http://en.wikipedia.org/wiki/Huffman_coding */ +BROTLI_INTERNAL void BrotliCreateHuffmanTree(const uint32_t* data, + const size_t length, + const int tree_limit, + HuffmanTree* tree, + uint8_t* depth); + +/* Change the population counts in a way that the consequent + Huffman tree compression, especially its RLE-part will be more + likely to compress this data more efficiently. + + length contains the size of the histogram. + counts contains the population counts. + good_for_rle is a buffer of at least length size */ +BROTLI_INTERNAL void BrotliOptimizeHuffmanCountsForRle( + size_t length, uint32_t* counts, uint8_t* good_for_rle); + +/* Write a Huffman tree from bit depths into the bit-stream representation + of a Huffman tree. The generated Huffman tree is to be compressed once + more using a Huffman tree */ +BROTLI_INTERNAL void BrotliWriteHuffmanTree(const uint8_t* depth, + size_t length, + size_t* tree_size, + uint8_t* tree, + uint8_t* extra_bits_data); + +/* Get the actual bit values for a tree of bit depths. */ +BROTLI_INTERNAL void BrotliConvertBitDepthsToSymbols(const uint8_t* depth, + size_t len, + uint16_t* bits); + +BROTLI_INTERNAL extern BROTLI_MODEL("small") const size_t kBrotliShellGaps[6]; +/* Input size optimized Shell sort. */ +typedef BROTLI_BOOL (*HuffmanTreeComparator)( + const HuffmanTree*, const HuffmanTree*); +static BROTLI_INLINE void SortHuffmanTreeItems(HuffmanTree* items, + const size_t n, HuffmanTreeComparator comparator) { + if (n < 13) { + /* Insertion sort. */ + size_t i; + for (i = 1; i < n; ++i) { + HuffmanTree tmp = items[i]; + size_t k = i; + size_t j = i - 1; + while (comparator(&tmp, &items[j])) { + items[k] = items[j]; + k = j; + if (!j--) break; + } + items[k] = tmp; + } + return; + } else { + /* Shell sort. */ + int g = n < 57 ? 2 : 0; + for (; g < 6; ++g) { + size_t gap = kBrotliShellGaps[g]; + size_t i; + for (i = gap; i < n; ++i) { + size_t j = i; + HuffmanTree tmp = items[i]; + for (; j >= gap && comparator(&tmp, &items[j - gap]); j -= gap) { + items[j] = items[j - gap]; + } + items[j] = tmp; + } + } + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_ENTROPY_ENCODE_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/entropy_encode_static.h b/packages/runtime/vendor/brotli/c/enc/entropy_encode_static.h new file mode 100644 index 000000000..5056eaa13 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/entropy_encode_static.h @@ -0,0 +1,548 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Static entropy codes used for faster meta-block encoding. */ + +#ifndef BROTLI_ENC_ENTROPY_ENCODE_STATIC_H_ +#define BROTLI_ENC_ENTROPY_ENCODE_STATIC_H_ + +#include "../common/constants.h" +#include "../common/platform.h" +#include "write_bits.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static const BROTLI_MODEL("small") uint8_t kCodeLengthDepth[18] = { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 0, 4, 4, +}; + +static const BROTLI_MODEL("small") +uint8_t kStaticCommandCodeDepth[BROTLI_NUM_COMMAND_SYMBOLS] = { + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +}; + +static const BROTLI_MODEL("small") +uint8_t kStaticDistanceCodeDepth[64] = { + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, +}; + +/* GENERATED CODE START */ +static const BROTLI_MODEL("small") +uint32_t kCodeLengthBits[18] = { + 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 15, 31, 0, 11, 7, +}; + +static BROTLI_INLINE void StoreStaticCodeLengthCode( + size_t* storage_ix, uint8_t* storage) { + BrotliWriteBits( + 40, BROTLI_MAKE_UINT64_T(0x0000FFu, 0x55555554u), storage_ix, storage); +} + +static const BROTLI_MODEL("small") +uint64_t kZeroRepsBits[BROTLI_NUM_COMMAND_SYMBOLS] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000017, 0x00000027, + 0x00000037, 0x00000047, 0x00000057, 0x00000067, 0x00000077, 0x00000770, + 0x00000b87, 0x00001387, 0x00001b87, 0x00002387, 0x00002b87, 0x00003387, + 0x00003b87, 0x00000397, 0x00000b97, 0x00001397, 0x00001b97, 0x00002397, + 0x00002b97, 0x00003397, 0x00003b97, 0x000003a7, 0x00000ba7, 0x000013a7, + 0x00001ba7, 0x000023a7, 0x00002ba7, 0x000033a7, 0x00003ba7, 0x000003b7, + 0x00000bb7, 0x000013b7, 0x00001bb7, 0x000023b7, 0x00002bb7, 0x000033b7, + 0x00003bb7, 0x000003c7, 0x00000bc7, 0x000013c7, 0x00001bc7, 0x000023c7, + 0x00002bc7, 0x000033c7, 0x00003bc7, 0x000003d7, 0x00000bd7, 0x000013d7, + 0x00001bd7, 0x000023d7, 0x00002bd7, 0x000033d7, 0x00003bd7, 0x000003e7, + 0x00000be7, 0x000013e7, 0x00001be7, 0x000023e7, 0x00002be7, 0x000033e7, + 0x00003be7, 0x000003f7, 0x00000bf7, 0x000013f7, 0x00001bf7, 0x000023f7, + 0x00002bf7, 0x000033f7, 0x00003bf7, 0x0001c387, 0x0005c387, 0x0009c387, + 0x000dc387, 0x0011c387, 0x0015c387, 0x0019c387, 0x001dc387, 0x0001cb87, + 0x0005cb87, 0x0009cb87, 0x000dcb87, 0x0011cb87, 0x0015cb87, 0x0019cb87, + 0x001dcb87, 0x0001d387, 0x0005d387, 0x0009d387, 0x000dd387, 0x0011d387, + 0x0015d387, 0x0019d387, 0x001dd387, 0x0001db87, 0x0005db87, 0x0009db87, + 0x000ddb87, 0x0011db87, 0x0015db87, 0x0019db87, 0x001ddb87, 0x0001e387, + 0x0005e387, 0x0009e387, 0x000de387, 0x0011e387, 0x0015e387, 0x0019e387, + 0x001de387, 0x0001eb87, 0x0005eb87, 0x0009eb87, 0x000deb87, 0x0011eb87, + 0x0015eb87, 0x0019eb87, 0x001deb87, 0x0001f387, 0x0005f387, 0x0009f387, + 0x000df387, 0x0011f387, 0x0015f387, 0x0019f387, 0x001df387, 0x0001fb87, + 0x0005fb87, 0x0009fb87, 0x000dfb87, 0x0011fb87, 0x0015fb87, 0x0019fb87, + 0x001dfb87, 0x0001c397, 0x0005c397, 0x0009c397, 0x000dc397, 0x0011c397, + 0x0015c397, 0x0019c397, 0x001dc397, 0x0001cb97, 0x0005cb97, 0x0009cb97, + 0x000dcb97, 0x0011cb97, 0x0015cb97, 0x0019cb97, 0x001dcb97, 0x0001d397, + 0x0005d397, 0x0009d397, 0x000dd397, 0x0011d397, 0x0015d397, 0x0019d397, + 0x001dd397, 0x0001db97, 0x0005db97, 0x0009db97, 0x000ddb97, 0x0011db97, + 0x0015db97, 0x0019db97, 0x001ddb97, 0x0001e397, 0x0005e397, 0x0009e397, + 0x000de397, 0x0011e397, 0x0015e397, 0x0019e397, 0x001de397, 0x0001eb97, + 0x0005eb97, 0x0009eb97, 0x000deb97, 0x0011eb97, 0x0015eb97, 0x0019eb97, + 0x001deb97, 0x0001f397, 0x0005f397, 0x0009f397, 0x000df397, 0x0011f397, + 0x0015f397, 0x0019f397, 0x001df397, 0x0001fb97, 0x0005fb97, 0x0009fb97, + 0x000dfb97, 0x0011fb97, 0x0015fb97, 0x0019fb97, 0x001dfb97, 0x0001c3a7, + 0x0005c3a7, 0x0009c3a7, 0x000dc3a7, 0x0011c3a7, 0x0015c3a7, 0x0019c3a7, + 0x001dc3a7, 0x0001cba7, 0x0005cba7, 0x0009cba7, 0x000dcba7, 0x0011cba7, + 0x0015cba7, 0x0019cba7, 0x001dcba7, 0x0001d3a7, 0x0005d3a7, 0x0009d3a7, + 0x000dd3a7, 0x0011d3a7, 0x0015d3a7, 0x0019d3a7, 0x001dd3a7, 0x0001dba7, + 0x0005dba7, 0x0009dba7, 0x000ddba7, 0x0011dba7, 0x0015dba7, 0x0019dba7, + 0x001ddba7, 0x0001e3a7, 0x0005e3a7, 0x0009e3a7, 0x000de3a7, 0x0011e3a7, + 0x0015e3a7, 0x0019e3a7, 0x001de3a7, 0x0001eba7, 0x0005eba7, 0x0009eba7, + 0x000deba7, 0x0011eba7, 0x0015eba7, 0x0019eba7, 0x001deba7, 0x0001f3a7, + 0x0005f3a7, 0x0009f3a7, 0x000df3a7, 0x0011f3a7, 0x0015f3a7, 0x0019f3a7, + 0x001df3a7, 0x0001fba7, 0x0005fba7, 0x0009fba7, 0x000dfba7, 0x0011fba7, + 0x0015fba7, 0x0019fba7, 0x001dfba7, 0x0001c3b7, 0x0005c3b7, 0x0009c3b7, + 0x000dc3b7, 0x0011c3b7, 0x0015c3b7, 0x0019c3b7, 0x001dc3b7, 0x0001cbb7, + 0x0005cbb7, 0x0009cbb7, 0x000dcbb7, 0x0011cbb7, 0x0015cbb7, 0x0019cbb7, + 0x001dcbb7, 0x0001d3b7, 0x0005d3b7, 0x0009d3b7, 0x000dd3b7, 0x0011d3b7, + 0x0015d3b7, 0x0019d3b7, 0x001dd3b7, 0x0001dbb7, 0x0005dbb7, 0x0009dbb7, + 0x000ddbb7, 0x0011dbb7, 0x0015dbb7, 0x0019dbb7, 0x001ddbb7, 0x0001e3b7, + 0x0005e3b7, 0x0009e3b7, 0x000de3b7, 0x0011e3b7, 0x0015e3b7, 0x0019e3b7, + 0x001de3b7, 0x0001ebb7, 0x0005ebb7, 0x0009ebb7, 0x000debb7, 0x0011ebb7, + 0x0015ebb7, 0x0019ebb7, 0x001debb7, 0x0001f3b7, 0x0005f3b7, 0x0009f3b7, + 0x000df3b7, 0x0011f3b7, 0x0015f3b7, 0x0019f3b7, 0x001df3b7, 0x0001fbb7, + 0x0005fbb7, 0x0009fbb7, 0x000dfbb7, 0x0011fbb7, 0x0015fbb7, 0x0019fbb7, + 0x001dfbb7, 0x0001c3c7, 0x0005c3c7, 0x0009c3c7, 0x000dc3c7, 0x0011c3c7, + 0x0015c3c7, 0x0019c3c7, 0x001dc3c7, 0x0001cbc7, 0x0005cbc7, 0x0009cbc7, + 0x000dcbc7, 0x0011cbc7, 0x0015cbc7, 0x0019cbc7, 0x001dcbc7, 0x0001d3c7, + 0x0005d3c7, 0x0009d3c7, 0x000dd3c7, 0x0011d3c7, 0x0015d3c7, 0x0019d3c7, + 0x001dd3c7, 0x0001dbc7, 0x0005dbc7, 0x0009dbc7, 0x000ddbc7, 0x0011dbc7, + 0x0015dbc7, 0x0019dbc7, 0x001ddbc7, 0x0001e3c7, 0x0005e3c7, 0x0009e3c7, + 0x000de3c7, 0x0011e3c7, 0x0015e3c7, 0x0019e3c7, 0x001de3c7, 0x0001ebc7, + 0x0005ebc7, 0x0009ebc7, 0x000debc7, 0x0011ebc7, 0x0015ebc7, 0x0019ebc7, + 0x001debc7, 0x0001f3c7, 0x0005f3c7, 0x0009f3c7, 0x000df3c7, 0x0011f3c7, + 0x0015f3c7, 0x0019f3c7, 0x001df3c7, 0x0001fbc7, 0x0005fbc7, 0x0009fbc7, + 0x000dfbc7, 0x0011fbc7, 0x0015fbc7, 0x0019fbc7, 0x001dfbc7, 0x0001c3d7, + 0x0005c3d7, 0x0009c3d7, 0x000dc3d7, 0x0011c3d7, 0x0015c3d7, 0x0019c3d7, + 0x001dc3d7, 0x0001cbd7, 0x0005cbd7, 0x0009cbd7, 0x000dcbd7, 0x0011cbd7, + 0x0015cbd7, 0x0019cbd7, 0x001dcbd7, 0x0001d3d7, 0x0005d3d7, 0x0009d3d7, + 0x000dd3d7, 0x0011d3d7, 0x0015d3d7, 0x0019d3d7, 0x001dd3d7, 0x0001dbd7, + 0x0005dbd7, 0x0009dbd7, 0x000ddbd7, 0x0011dbd7, 0x0015dbd7, 0x0019dbd7, + 0x001ddbd7, 0x0001e3d7, 0x0005e3d7, 0x0009e3d7, 0x000de3d7, 0x0011e3d7, + 0x0015e3d7, 0x0019e3d7, 0x001de3d7, 0x0001ebd7, 0x0005ebd7, 0x0009ebd7, + 0x000debd7, 0x0011ebd7, 0x0015ebd7, 0x0019ebd7, 0x001debd7, 0x0001f3d7, + 0x0005f3d7, 0x0009f3d7, 0x000df3d7, 0x0011f3d7, 0x0015f3d7, 0x0019f3d7, + 0x001df3d7, 0x0001fbd7, 0x0005fbd7, 0x0009fbd7, 0x000dfbd7, 0x0011fbd7, + 0x0015fbd7, 0x0019fbd7, 0x001dfbd7, 0x0001c3e7, 0x0005c3e7, 0x0009c3e7, + 0x000dc3e7, 0x0011c3e7, 0x0015c3e7, 0x0019c3e7, 0x001dc3e7, 0x0001cbe7, + 0x0005cbe7, 0x0009cbe7, 0x000dcbe7, 0x0011cbe7, 0x0015cbe7, 0x0019cbe7, + 0x001dcbe7, 0x0001d3e7, 0x0005d3e7, 0x0009d3e7, 0x000dd3e7, 0x0011d3e7, + 0x0015d3e7, 0x0019d3e7, 0x001dd3e7, 0x0001dbe7, 0x0005dbe7, 0x0009dbe7, + 0x000ddbe7, 0x0011dbe7, 0x0015dbe7, 0x0019dbe7, 0x001ddbe7, 0x0001e3e7, + 0x0005e3e7, 0x0009e3e7, 0x000de3e7, 0x0011e3e7, 0x0015e3e7, 0x0019e3e7, + 0x001de3e7, 0x0001ebe7, 0x0005ebe7, 0x0009ebe7, 0x000debe7, 0x0011ebe7, + 0x0015ebe7, 0x0019ebe7, 0x001debe7, 0x0001f3e7, 0x0005f3e7, 0x0009f3e7, + 0x000df3e7, 0x0011f3e7, 0x0015f3e7, 0x0019f3e7, 0x001df3e7, 0x0001fbe7, + 0x0005fbe7, 0x0009fbe7, 0x000dfbe7, 0x0011fbe7, 0x0015fbe7, 0x0019fbe7, + 0x001dfbe7, 0x0001c3f7, 0x0005c3f7, 0x0009c3f7, 0x000dc3f7, 0x0011c3f7, + 0x0015c3f7, 0x0019c3f7, 0x001dc3f7, 0x0001cbf7, 0x0005cbf7, 0x0009cbf7, + 0x000dcbf7, 0x0011cbf7, 0x0015cbf7, 0x0019cbf7, 0x001dcbf7, 0x0001d3f7, + 0x0005d3f7, 0x0009d3f7, 0x000dd3f7, 0x0011d3f7, 0x0015d3f7, 0x0019d3f7, + 0x001dd3f7, 0x0001dbf7, 0x0005dbf7, 0x0009dbf7, 0x000ddbf7, 0x0011dbf7, + 0x0015dbf7, 0x0019dbf7, 0x001ddbf7, 0x0001e3f7, 0x0005e3f7, 0x0009e3f7, + 0x000de3f7, 0x0011e3f7, 0x0015e3f7, 0x0019e3f7, 0x001de3f7, 0x0001ebf7, + 0x0005ebf7, 0x0009ebf7, 0x000debf7, 0x0011ebf7, 0x0015ebf7, 0x0019ebf7, + 0x001debf7, 0x0001f3f7, 0x0005f3f7, 0x0009f3f7, 0x000df3f7, 0x0011f3f7, + 0x0015f3f7, 0x0019f3f7, 0x001df3f7, 0x0001fbf7, 0x0005fbf7, 0x0009fbf7, + 0x000dfbf7, 0x0011fbf7, 0x0015fbf7, 0x0019fbf7, 0x001dfbf7, 0x00e1c387, + 0x02e1c387, 0x04e1c387, 0x06e1c387, 0x08e1c387, 0x0ae1c387, 0x0ce1c387, + 0x0ee1c387, 0x00e5c387, 0x02e5c387, 0x04e5c387, 0x06e5c387, 0x08e5c387, + 0x0ae5c387, 0x0ce5c387, 0x0ee5c387, 0x00e9c387, 0x02e9c387, 0x04e9c387, + 0x06e9c387, 0x08e9c387, 0x0ae9c387, 0x0ce9c387, 0x0ee9c387, 0x00edc387, + 0x02edc387, 0x04edc387, 0x06edc387, 0x08edc387, 0x0aedc387, 0x0cedc387, + 0x0eedc387, 0x00f1c387, 0x02f1c387, 0x04f1c387, 0x06f1c387, 0x08f1c387, + 0x0af1c387, 0x0cf1c387, 0x0ef1c387, 0x00f5c387, 0x02f5c387, 0x04f5c387, + 0x06f5c387, 0x08f5c387, 0x0af5c387, 0x0cf5c387, 0x0ef5c387, 0x00f9c387, + 0x02f9c387, 0x04f9c387, 0x06f9c387, 0x08f9c387, 0x0af9c387, 0x0cf9c387, + 0x0ef9c387, 0x00fdc387, 0x02fdc387, 0x04fdc387, 0x06fdc387, 0x08fdc387, + 0x0afdc387, 0x0cfdc387, 0x0efdc387, 0x00e1cb87, 0x02e1cb87, 0x04e1cb87, + 0x06e1cb87, 0x08e1cb87, 0x0ae1cb87, 0x0ce1cb87, 0x0ee1cb87, 0x00e5cb87, + 0x02e5cb87, 0x04e5cb87, 0x06e5cb87, 0x08e5cb87, 0x0ae5cb87, 0x0ce5cb87, + 0x0ee5cb87, 0x00e9cb87, 0x02e9cb87, 0x04e9cb87, 0x06e9cb87, 0x08e9cb87, + 0x0ae9cb87, 0x0ce9cb87, 0x0ee9cb87, 0x00edcb87, 0x02edcb87, 0x04edcb87, + 0x06edcb87, 0x08edcb87, 0x0aedcb87, 0x0cedcb87, 0x0eedcb87, 0x00f1cb87, + 0x02f1cb87, 0x04f1cb87, 0x06f1cb87, 0x08f1cb87, 0x0af1cb87, 0x0cf1cb87, + 0x0ef1cb87, 0x00f5cb87, 0x02f5cb87, 0x04f5cb87, 0x06f5cb87, 0x08f5cb87, + 0x0af5cb87, 0x0cf5cb87, 0x0ef5cb87, 0x00f9cb87, 0x02f9cb87, 0x04f9cb87, + 0x06f9cb87, 0x08f9cb87, +}; + +static const BROTLI_MODEL("small") +uint32_t kZeroRepsDepth[BROTLI_NUM_COMMAND_SYMBOLS] = { + 0, 4, 8, 7, 7, 7, 7, 7, 7, 7, 7, 11, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +}; + +static const BROTLI_MODEL("small") +uint64_t kNonZeroRepsBits[BROTLI_NUM_COMMAND_SYMBOLS] = { + 0x0000000b, 0x0000001b, 0x0000002b, 0x0000003b, 0x000002cb, 0x000006cb, + 0x00000acb, 0x00000ecb, 0x000002db, 0x000006db, 0x00000adb, 0x00000edb, + 0x000002eb, 0x000006eb, 0x00000aeb, 0x00000eeb, 0x000002fb, 0x000006fb, + 0x00000afb, 0x00000efb, 0x0000b2cb, 0x0001b2cb, 0x0002b2cb, 0x0003b2cb, + 0x0000b6cb, 0x0001b6cb, 0x0002b6cb, 0x0003b6cb, 0x0000bacb, 0x0001bacb, + 0x0002bacb, 0x0003bacb, 0x0000becb, 0x0001becb, 0x0002becb, 0x0003becb, + 0x0000b2db, 0x0001b2db, 0x0002b2db, 0x0003b2db, 0x0000b6db, 0x0001b6db, + 0x0002b6db, 0x0003b6db, 0x0000badb, 0x0001badb, 0x0002badb, 0x0003badb, + 0x0000bedb, 0x0001bedb, 0x0002bedb, 0x0003bedb, 0x0000b2eb, 0x0001b2eb, + 0x0002b2eb, 0x0003b2eb, 0x0000b6eb, 0x0001b6eb, 0x0002b6eb, 0x0003b6eb, + 0x0000baeb, 0x0001baeb, 0x0002baeb, 0x0003baeb, 0x0000beeb, 0x0001beeb, + 0x0002beeb, 0x0003beeb, 0x0000b2fb, 0x0001b2fb, 0x0002b2fb, 0x0003b2fb, + 0x0000b6fb, 0x0001b6fb, 0x0002b6fb, 0x0003b6fb, 0x0000bafb, 0x0001bafb, + 0x0002bafb, 0x0003bafb, 0x0000befb, 0x0001befb, 0x0002befb, 0x0003befb, + 0x002cb2cb, 0x006cb2cb, 0x00acb2cb, 0x00ecb2cb, 0x002db2cb, 0x006db2cb, + 0x00adb2cb, 0x00edb2cb, 0x002eb2cb, 0x006eb2cb, 0x00aeb2cb, 0x00eeb2cb, + 0x002fb2cb, 0x006fb2cb, 0x00afb2cb, 0x00efb2cb, 0x002cb6cb, 0x006cb6cb, + 0x00acb6cb, 0x00ecb6cb, 0x002db6cb, 0x006db6cb, 0x00adb6cb, 0x00edb6cb, + 0x002eb6cb, 0x006eb6cb, 0x00aeb6cb, 0x00eeb6cb, 0x002fb6cb, 0x006fb6cb, + 0x00afb6cb, 0x00efb6cb, 0x002cbacb, 0x006cbacb, 0x00acbacb, 0x00ecbacb, + 0x002dbacb, 0x006dbacb, 0x00adbacb, 0x00edbacb, 0x002ebacb, 0x006ebacb, + 0x00aebacb, 0x00eebacb, 0x002fbacb, 0x006fbacb, 0x00afbacb, 0x00efbacb, + 0x002cbecb, 0x006cbecb, 0x00acbecb, 0x00ecbecb, 0x002dbecb, 0x006dbecb, + 0x00adbecb, 0x00edbecb, 0x002ebecb, 0x006ebecb, 0x00aebecb, 0x00eebecb, + 0x002fbecb, 0x006fbecb, 0x00afbecb, 0x00efbecb, 0x002cb2db, 0x006cb2db, + 0x00acb2db, 0x00ecb2db, 0x002db2db, 0x006db2db, 0x00adb2db, 0x00edb2db, + 0x002eb2db, 0x006eb2db, 0x00aeb2db, 0x00eeb2db, 0x002fb2db, 0x006fb2db, + 0x00afb2db, 0x00efb2db, 0x002cb6db, 0x006cb6db, 0x00acb6db, 0x00ecb6db, + 0x002db6db, 0x006db6db, 0x00adb6db, 0x00edb6db, 0x002eb6db, 0x006eb6db, + 0x00aeb6db, 0x00eeb6db, 0x002fb6db, 0x006fb6db, 0x00afb6db, 0x00efb6db, + 0x002cbadb, 0x006cbadb, 0x00acbadb, 0x00ecbadb, 0x002dbadb, 0x006dbadb, + 0x00adbadb, 0x00edbadb, 0x002ebadb, 0x006ebadb, 0x00aebadb, 0x00eebadb, + 0x002fbadb, 0x006fbadb, 0x00afbadb, 0x00efbadb, 0x002cbedb, 0x006cbedb, + 0x00acbedb, 0x00ecbedb, 0x002dbedb, 0x006dbedb, 0x00adbedb, 0x00edbedb, + 0x002ebedb, 0x006ebedb, 0x00aebedb, 0x00eebedb, 0x002fbedb, 0x006fbedb, + 0x00afbedb, 0x00efbedb, 0x002cb2eb, 0x006cb2eb, 0x00acb2eb, 0x00ecb2eb, + 0x002db2eb, 0x006db2eb, 0x00adb2eb, 0x00edb2eb, 0x002eb2eb, 0x006eb2eb, + 0x00aeb2eb, 0x00eeb2eb, 0x002fb2eb, 0x006fb2eb, 0x00afb2eb, 0x00efb2eb, + 0x002cb6eb, 0x006cb6eb, 0x00acb6eb, 0x00ecb6eb, 0x002db6eb, 0x006db6eb, + 0x00adb6eb, 0x00edb6eb, 0x002eb6eb, 0x006eb6eb, 0x00aeb6eb, 0x00eeb6eb, + 0x002fb6eb, 0x006fb6eb, 0x00afb6eb, 0x00efb6eb, 0x002cbaeb, 0x006cbaeb, + 0x00acbaeb, 0x00ecbaeb, 0x002dbaeb, 0x006dbaeb, 0x00adbaeb, 0x00edbaeb, + 0x002ebaeb, 0x006ebaeb, 0x00aebaeb, 0x00eebaeb, 0x002fbaeb, 0x006fbaeb, + 0x00afbaeb, 0x00efbaeb, 0x002cbeeb, 0x006cbeeb, 0x00acbeeb, 0x00ecbeeb, + 0x002dbeeb, 0x006dbeeb, 0x00adbeeb, 0x00edbeeb, 0x002ebeeb, 0x006ebeeb, + 0x00aebeeb, 0x00eebeeb, 0x002fbeeb, 0x006fbeeb, 0x00afbeeb, 0x00efbeeb, + 0x002cb2fb, 0x006cb2fb, 0x00acb2fb, 0x00ecb2fb, 0x002db2fb, 0x006db2fb, + 0x00adb2fb, 0x00edb2fb, 0x002eb2fb, 0x006eb2fb, 0x00aeb2fb, 0x00eeb2fb, + 0x002fb2fb, 0x006fb2fb, 0x00afb2fb, 0x00efb2fb, 0x002cb6fb, 0x006cb6fb, + 0x00acb6fb, 0x00ecb6fb, 0x002db6fb, 0x006db6fb, 0x00adb6fb, 0x00edb6fb, + 0x002eb6fb, 0x006eb6fb, 0x00aeb6fb, 0x00eeb6fb, 0x002fb6fb, 0x006fb6fb, + 0x00afb6fb, 0x00efb6fb, 0x002cbafb, 0x006cbafb, 0x00acbafb, 0x00ecbafb, + 0x002dbafb, 0x006dbafb, 0x00adbafb, 0x00edbafb, 0x002ebafb, 0x006ebafb, + 0x00aebafb, 0x00eebafb, 0x002fbafb, 0x006fbafb, 0x00afbafb, 0x00efbafb, + 0x002cbefb, 0x006cbefb, 0x00acbefb, 0x00ecbefb, 0x002dbefb, 0x006dbefb, + 0x00adbefb, 0x00edbefb, 0x002ebefb, 0x006ebefb, 0x00aebefb, 0x00eebefb, + 0x002fbefb, 0x006fbefb, 0x00afbefb, 0x00efbefb, 0x0b2cb2cb, 0x1b2cb2cb, + 0x2b2cb2cb, 0x3b2cb2cb, 0x0b6cb2cb, 0x1b6cb2cb, 0x2b6cb2cb, 0x3b6cb2cb, + 0x0bacb2cb, 0x1bacb2cb, 0x2bacb2cb, 0x3bacb2cb, 0x0becb2cb, 0x1becb2cb, + 0x2becb2cb, 0x3becb2cb, 0x0b2db2cb, 0x1b2db2cb, 0x2b2db2cb, 0x3b2db2cb, + 0x0b6db2cb, 0x1b6db2cb, 0x2b6db2cb, 0x3b6db2cb, 0x0badb2cb, 0x1badb2cb, + 0x2badb2cb, 0x3badb2cb, 0x0bedb2cb, 0x1bedb2cb, 0x2bedb2cb, 0x3bedb2cb, + 0x0b2eb2cb, 0x1b2eb2cb, 0x2b2eb2cb, 0x3b2eb2cb, 0x0b6eb2cb, 0x1b6eb2cb, + 0x2b6eb2cb, 0x3b6eb2cb, 0x0baeb2cb, 0x1baeb2cb, 0x2baeb2cb, 0x3baeb2cb, + 0x0beeb2cb, 0x1beeb2cb, 0x2beeb2cb, 0x3beeb2cb, 0x0b2fb2cb, 0x1b2fb2cb, + 0x2b2fb2cb, 0x3b2fb2cb, 0x0b6fb2cb, 0x1b6fb2cb, 0x2b6fb2cb, 0x3b6fb2cb, + 0x0bafb2cb, 0x1bafb2cb, 0x2bafb2cb, 0x3bafb2cb, 0x0befb2cb, 0x1befb2cb, + 0x2befb2cb, 0x3befb2cb, 0x0b2cb6cb, 0x1b2cb6cb, 0x2b2cb6cb, 0x3b2cb6cb, + 0x0b6cb6cb, 0x1b6cb6cb, 0x2b6cb6cb, 0x3b6cb6cb, 0x0bacb6cb, 0x1bacb6cb, + 0x2bacb6cb, 0x3bacb6cb, 0x0becb6cb, 0x1becb6cb, 0x2becb6cb, 0x3becb6cb, + 0x0b2db6cb, 0x1b2db6cb, 0x2b2db6cb, 0x3b2db6cb, 0x0b6db6cb, 0x1b6db6cb, + 0x2b6db6cb, 0x3b6db6cb, 0x0badb6cb, 0x1badb6cb, 0x2badb6cb, 0x3badb6cb, + 0x0bedb6cb, 0x1bedb6cb, 0x2bedb6cb, 0x3bedb6cb, 0x0b2eb6cb, 0x1b2eb6cb, + 0x2b2eb6cb, 0x3b2eb6cb, 0x0b6eb6cb, 0x1b6eb6cb, 0x2b6eb6cb, 0x3b6eb6cb, + 0x0baeb6cb, 0x1baeb6cb, 0x2baeb6cb, 0x3baeb6cb, 0x0beeb6cb, 0x1beeb6cb, + 0x2beeb6cb, 0x3beeb6cb, 0x0b2fb6cb, 0x1b2fb6cb, 0x2b2fb6cb, 0x3b2fb6cb, + 0x0b6fb6cb, 0x1b6fb6cb, 0x2b6fb6cb, 0x3b6fb6cb, 0x0bafb6cb, 0x1bafb6cb, + 0x2bafb6cb, 0x3bafb6cb, 0x0befb6cb, 0x1befb6cb, 0x2befb6cb, 0x3befb6cb, + 0x0b2cbacb, 0x1b2cbacb, 0x2b2cbacb, 0x3b2cbacb, 0x0b6cbacb, 0x1b6cbacb, + 0x2b6cbacb, 0x3b6cbacb, 0x0bacbacb, 0x1bacbacb, 0x2bacbacb, 0x3bacbacb, + 0x0becbacb, 0x1becbacb, 0x2becbacb, 0x3becbacb, 0x0b2dbacb, 0x1b2dbacb, + 0x2b2dbacb, 0x3b2dbacb, 0x0b6dbacb, 0x1b6dbacb, 0x2b6dbacb, 0x3b6dbacb, + 0x0badbacb, 0x1badbacb, 0x2badbacb, 0x3badbacb, 0x0bedbacb, 0x1bedbacb, + 0x2bedbacb, 0x3bedbacb, 0x0b2ebacb, 0x1b2ebacb, 0x2b2ebacb, 0x3b2ebacb, + 0x0b6ebacb, 0x1b6ebacb, 0x2b6ebacb, 0x3b6ebacb, 0x0baebacb, 0x1baebacb, + 0x2baebacb, 0x3baebacb, 0x0beebacb, 0x1beebacb, 0x2beebacb, 0x3beebacb, + 0x0b2fbacb, 0x1b2fbacb, 0x2b2fbacb, 0x3b2fbacb, 0x0b6fbacb, 0x1b6fbacb, + 0x2b6fbacb, 0x3b6fbacb, 0x0bafbacb, 0x1bafbacb, 0x2bafbacb, 0x3bafbacb, + 0x0befbacb, 0x1befbacb, 0x2befbacb, 0x3befbacb, 0x0b2cbecb, 0x1b2cbecb, + 0x2b2cbecb, 0x3b2cbecb, 0x0b6cbecb, 0x1b6cbecb, 0x2b6cbecb, 0x3b6cbecb, + 0x0bacbecb, 0x1bacbecb, 0x2bacbecb, 0x3bacbecb, 0x0becbecb, 0x1becbecb, + 0x2becbecb, 0x3becbecb, 0x0b2dbecb, 0x1b2dbecb, 0x2b2dbecb, 0x3b2dbecb, + 0x0b6dbecb, 0x1b6dbecb, 0x2b6dbecb, 0x3b6dbecb, 0x0badbecb, 0x1badbecb, + 0x2badbecb, 0x3badbecb, 0x0bedbecb, 0x1bedbecb, 0x2bedbecb, 0x3bedbecb, + 0x0b2ebecb, 0x1b2ebecb, 0x2b2ebecb, 0x3b2ebecb, 0x0b6ebecb, 0x1b6ebecb, + 0x2b6ebecb, 0x3b6ebecb, 0x0baebecb, 0x1baebecb, 0x2baebecb, 0x3baebecb, + 0x0beebecb, 0x1beebecb, 0x2beebecb, 0x3beebecb, 0x0b2fbecb, 0x1b2fbecb, + 0x2b2fbecb, 0x3b2fbecb, 0x0b6fbecb, 0x1b6fbecb, 0x2b6fbecb, 0x3b6fbecb, + 0x0bafbecb, 0x1bafbecb, 0x2bafbecb, 0x3bafbecb, 0x0befbecb, 0x1befbecb, + 0x2befbecb, 0x3befbecb, 0x0b2cb2db, 0x1b2cb2db, 0x2b2cb2db, 0x3b2cb2db, + 0x0b6cb2db, 0x1b6cb2db, 0x2b6cb2db, 0x3b6cb2db, 0x0bacb2db, 0x1bacb2db, + 0x2bacb2db, 0x3bacb2db, 0x0becb2db, 0x1becb2db, 0x2becb2db, 0x3becb2db, + 0x0b2db2db, 0x1b2db2db, 0x2b2db2db, 0x3b2db2db, 0x0b6db2db, 0x1b6db2db, + 0x2b6db2db, 0x3b6db2db, 0x0badb2db, 0x1badb2db, 0x2badb2db, 0x3badb2db, + 0x0bedb2db, 0x1bedb2db, 0x2bedb2db, 0x3bedb2db, 0x0b2eb2db, 0x1b2eb2db, + 0x2b2eb2db, 0x3b2eb2db, 0x0b6eb2db, 0x1b6eb2db, 0x2b6eb2db, 0x3b6eb2db, + 0x0baeb2db, 0x1baeb2db, 0x2baeb2db, 0x3baeb2db, 0x0beeb2db, 0x1beeb2db, + 0x2beeb2db, 0x3beeb2db, 0x0b2fb2db, 0x1b2fb2db, 0x2b2fb2db, 0x3b2fb2db, + 0x0b6fb2db, 0x1b6fb2db, 0x2b6fb2db, 0x3b6fb2db, 0x0bafb2db, 0x1bafb2db, + 0x2bafb2db, 0x3bafb2db, 0x0befb2db, 0x1befb2db, 0x2befb2db, 0x3befb2db, + 0x0b2cb6db, 0x1b2cb6db, 0x2b2cb6db, 0x3b2cb6db, 0x0b6cb6db, 0x1b6cb6db, + 0x2b6cb6db, 0x3b6cb6db, 0x0bacb6db, 0x1bacb6db, 0x2bacb6db, 0x3bacb6db, + 0x0becb6db, 0x1becb6db, 0x2becb6db, 0x3becb6db, 0x0b2db6db, 0x1b2db6db, + 0x2b2db6db, 0x3b2db6db, 0x0b6db6db, 0x1b6db6db, 0x2b6db6db, 0x3b6db6db, + 0x0badb6db, 0x1badb6db, 0x2badb6db, 0x3badb6db, 0x0bedb6db, 0x1bedb6db, + 0x2bedb6db, 0x3bedb6db, 0x0b2eb6db, 0x1b2eb6db, 0x2b2eb6db, 0x3b2eb6db, + 0x0b6eb6db, 0x1b6eb6db, 0x2b6eb6db, 0x3b6eb6db, 0x0baeb6db, 0x1baeb6db, + 0x2baeb6db, 0x3baeb6db, +}; + +static const BROTLI_MODEL("small") +uint32_t kNonZeroRepsDepth[BROTLI_NUM_COMMAND_SYMBOLS] = { + 6, 6, 6, 6, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, +}; + +static const BROTLI_MODEL("small") +uint16_t kStaticCommandCodeBits[BROTLI_NUM_COMMAND_SYMBOLS] = { + 0, 256, 128, 384, 64, 320, 192, 448, + 32, 288, 160, 416, 96, 352, 224, 480, + 16, 272, 144, 400, 80, 336, 208, 464, + 48, 304, 176, 432, 112, 368, 240, 496, + 8, 264, 136, 392, 72, 328, 200, 456, + 40, 296, 168, 424, 104, 360, 232, 488, + 24, 280, 152, 408, 88, 344, 216, 472, + 56, 312, 184, 440, 120, 376, 248, 504, + 4, 260, 132, 388, 68, 324, 196, 452, + 36, 292, 164, 420, 100, 356, 228, 484, + 20, 276, 148, 404, 84, 340, 212, 468, + 52, 308, 180, 436, 116, 372, 244, 500, + 12, 268, 140, 396, 76, 332, 204, 460, + 44, 300, 172, 428, 108, 364, 236, 492, + 28, 284, 156, 412, 92, 348, 220, 476, + 60, 316, 188, 444, 124, 380, 252, 508, + 2, 258, 130, 386, 66, 322, 194, 450, + 34, 290, 162, 418, 98, 354, 226, 482, + 18, 274, 146, 402, 82, 338, 210, 466, + 50, 306, 178, 434, 114, 370, 242, 498, + 10, 266, 138, 394, 74, 330, 202, 458, + 42, 298, 170, 426, 106, 362, 234, 490, + 26, 282, 154, 410, 90, 346, 218, 474, + 58, 314, 186, 442, 122, 378, 250, 506, + 6, 262, 134, 390, 70, 326, 198, 454, + 38, 294, 166, 422, 102, 358, 230, 486, + 22, 278, 150, 406, 86, 342, 214, 470, + 54, 310, 182, 438, 118, 374, 246, 502, + 14, 270, 142, 398, 78, 334, 206, 462, + 46, 302, 174, 430, 110, 366, 238, 494, + 30, 286, 158, 414, 94, 350, 222, 478, + 62, 318, 190, 446, 126, 382, 254, 510, + 1, 257, 129, 385, 65, 321, 193, 449, + 33, 289, 161, 417, 97, 353, 225, 481, + 17, 273, 145, 401, 81, 337, 209, 465, + 49, 305, 177, 433, 113, 369, 241, 497, + 9, 265, 137, 393, 73, 329, 201, 457, + 41, 297, 169, 425, 105, 361, 233, 489, + 25, 281, 153, 409, 89, 345, 217, 473, + 57, 313, 185, 441, 121, 377, 249, 505, + 5, 261, 133, 389, 69, 325, 197, 453, + 37, 293, 165, 421, 101, 357, 229, 485, + 21, 277, 149, 405, 85, 341, 213, 469, + 53, 309, 181, 437, 117, 373, 245, 501, + 13, 269, 141, 397, 77, 333, 205, 461, + 45, 301, 173, 429, 109, 365, 237, 493, + 29, 285, 157, 413, 93, 349, 221, 477, + 61, 317, 189, 445, 125, 381, 253, 509, + 3, 259, 131, 387, 67, 323, 195, 451, + 35, 291, 163, 419, 99, 355, 227, 483, + 19, 275, 147, 403, 83, 339, 211, 467, + 51, 307, 179, 435, 115, 371, 243, 499, + 11, 267, 139, 395, 75, 331, 203, 459, + 43, 299, 171, 427, 107, 363, 235, 491, + 27, 283, 155, 411, 91, 347, 219, 475, + 59, 315, 187, 443, 123, 379, 251, 507, + 7, 1031, 519, 1543, 263, 1287, 775, 1799, + 135, 1159, 647, 1671, 391, 1415, 903, 1927, + 71, 1095, 583, 1607, 327, 1351, 839, 1863, + 199, 1223, 711, 1735, 455, 1479, 967, 1991, + 39, 1063, 551, 1575, 295, 1319, 807, 1831, + 167, 1191, 679, 1703, 423, 1447, 935, 1959, + 103, 1127, 615, 1639, 359, 1383, 871, 1895, + 231, 1255, 743, 1767, 487, 1511, 999, 2023, + 23, 1047, 535, 1559, 279, 1303, 791, 1815, + 151, 1175, 663, 1687, 407, 1431, 919, 1943, + 87, 1111, 599, 1623, 343, 1367, 855, 1879, + 215, 1239, 727, 1751, 471, 1495, 983, 2007, + 55, 1079, 567, 1591, 311, 1335, 823, 1847, + 183, 1207, 695, 1719, 439, 1463, 951, 1975, + 119, 1143, 631, 1655, 375, 1399, 887, 1911, + 247, 1271, 759, 1783, 503, 1527, 1015, 2039, + 15, 1039, 527, 1551, 271, 1295, 783, 1807, + 143, 1167, 655, 1679, 399, 1423, 911, 1935, + 79, 1103, 591, 1615, 335, 1359, 847, 1871, + 207, 1231, 719, 1743, 463, 1487, 975, 1999, + 47, 1071, 559, 1583, 303, 1327, 815, 1839, + 175, 1199, 687, 1711, 431, 1455, 943, 1967, + 111, 1135, 623, 1647, 367, 1391, 879, 1903, + 239, 1263, 751, 1775, 495, 1519, 1007, 2031, + 31, 1055, 543, 1567, 287, 1311, 799, 1823, + 159, 1183, 671, 1695, 415, 1439, 927, 1951, + 95, 1119, 607, 1631, 351, 1375, 863, 1887, + 223, 1247, 735, 1759, 479, 1503, 991, 2015, + 63, 1087, 575, 1599, 319, 1343, 831, 1855, + 191, 1215, 703, 1727, 447, 1471, 959, 1983, + 127, 1151, 639, 1663, 383, 1407, 895, 1919, + 255, 1279, 767, 1791, 511, 1535, 1023, 2047, +}; + +static BROTLI_INLINE void StoreStaticCommandHuffmanTree( + size_t* storage_ix, uint8_t* storage) { + BrotliWriteBits( + 56, BROTLI_MAKE_UINT64_T(0x926244U, 0x16307003U), storage_ix, storage); + BrotliWriteBits(3, 0x00000000U, storage_ix, storage); +} + +static const BROTLI_MODEL("small") uint16_t kStaticDistanceCodeBits[64] = { + 0, 32, 16, 48, 8, 40, 24, 56, 4, 36, 20, 52, 12, 44, 28, 60, + 2, 34, 18, 50, 10, 42, 26, 58, 6, 38, 22, 54, 14, 46, 30, 62, + 1, 33, 17, 49, 9, 41, 25, 57, 5, 37, 21, 53, 13, 45, 29, 61, + 3, 35, 19, 51, 11, 43, 27, 59, 7, 39, 23, 55, 15, 47, 31, 63, +}; + +static BROTLI_INLINE void StoreStaticDistanceHuffmanTree( + size_t* storage_ix, uint8_t* storage) { + BrotliWriteBits(28, 0x0369DC03u, storage_ix, storage); +} +/* GENERATED CODE END */ + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_ENTROPY_ENCODE_STATIC_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/fast_log.c b/packages/runtime/vendor/brotli/c/enc/fast_log.c new file mode 100644 index 000000000..7b7ac0295 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/fast_log.c @@ -0,0 +1,105 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "fast_log.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* ", ".join(["%.16ff" % x for x in [0.0]+[log2(x) for x in range(1, 256)]]) */ +const BROTLI_MODEL("small") double kBrotliLog2Table[BROTLI_LOG2_TABLE_SIZE] = { + 0.0000000000000000f, 0.0000000000000000f, 1.0000000000000000f, + 1.5849625007211563f, 2.0000000000000000f, 2.3219280948873622f, + 2.5849625007211561f, 2.8073549220576042f, 3.0000000000000000f, + 3.1699250014423126f, 3.3219280948873626f, 3.4594316186372978f, + 3.5849625007211565f, 3.7004397181410922f, 3.8073549220576037f, + 3.9068905956085187f, 4.0000000000000000f, 4.0874628412503400f, + 4.1699250014423122f, 4.2479275134435852f, 4.3219280948873626f, + 4.3923174227787607f, 4.4594316186372973f, 4.5235619560570131f, + 4.5849625007211570f, 4.6438561897747244f, 4.7004397181410926f, + 4.7548875021634691f, 4.8073549220576037f, 4.8579809951275728f, + 4.9068905956085187f, 4.9541963103868758f, 5.0000000000000000f, + 5.0443941193584534f, 5.0874628412503400f, 5.1292830169449664f, + 5.1699250014423122f, 5.2094533656289501f, 5.2479275134435852f, + 5.2854022188622487f, 5.3219280948873626f, 5.3575520046180838f, + 5.3923174227787607f, 5.4262647547020979f, 5.4594316186372973f, + 5.4918530963296748f, 5.5235619560570131f, 5.5545888516776376f, + 5.5849625007211570f, 5.6147098441152083f, 5.6438561897747244f, + 5.6724253419714961f, 5.7004397181410926f, 5.7279204545631996f, + 5.7548875021634691f, 5.7813597135246599f, 5.8073549220576046f, + 5.8328900141647422f, 5.8579809951275719f, 5.8826430493618416f, + 5.9068905956085187f, 5.9307373375628867f, 5.9541963103868758f, + 5.9772799234999168f, 6.0000000000000000f, 6.0223678130284544f, + 6.0443941193584534f, 6.0660891904577721f, 6.0874628412503400f, + 6.1085244567781700f, 6.1292830169449672f, 6.1497471195046822f, + 6.1699250014423122f, 6.1898245588800176f, 6.2094533656289510f, + 6.2288186904958804f, 6.2479275134435861f, 6.2667865406949019f, + 6.2854022188622487f, 6.3037807481771031f, 6.3219280948873617f, + 6.3398500028846252f, 6.3575520046180847f, 6.3750394313469254f, + 6.3923174227787598f, 6.4093909361377026f, 6.4262647547020979f, + 6.4429434958487288f, 6.4594316186372982f, 6.4757334309663976f, + 6.4918530963296748f, 6.5077946401986964f, 6.5235619560570131f, + 6.5391588111080319f, 6.5545888516776376f, 6.5698556083309478f, + 6.5849625007211561f, 6.5999128421871278f, 6.6147098441152092f, + 6.6293566200796095f, 6.6438561897747253f, 6.6582114827517955f, + 6.6724253419714952f, 6.6865005271832185f, 6.7004397181410917f, + 6.7142455176661224f, 6.7279204545631988f, 6.7414669864011465f, + 6.7548875021634691f, 6.7681843247769260f, 6.7813597135246599f, + 6.7944158663501062f, 6.8073549220576037f, 6.8201789624151887f, + 6.8328900141647422f, 6.8454900509443757f, 6.8579809951275719f, + 6.8703647195834048f, 6.8826430493618416f, 6.8948177633079437f, + 6.9068905956085187f, 6.9188632372745955f, 6.9307373375628867f, + 6.9425145053392399f, 6.9541963103868758f, 6.9657842846620879f, + 6.9772799234999168f, 6.9886846867721664f, 7.0000000000000000f, + 7.0112272554232540f, 7.0223678130284544f, 7.0334230015374501f, + 7.0443941193584534f, 7.0552824355011898f, 7.0660891904577721f, + 7.0768155970508317f, 7.0874628412503400f, 7.0980320829605272f, + 7.1085244567781700f, 7.1189410727235076f, 7.1292830169449664f, + 7.1395513523987937f, 7.1497471195046822f, 7.1598713367783891f, + 7.1699250014423130f, 7.1799090900149345f, 7.1898245588800176f, + 7.1996723448363644f, 7.2094533656289492f, 7.2191685204621621f, + 7.2288186904958804f, 7.2384047393250794f, 7.2479275134435861f, + 7.2573878426926521f, 7.2667865406949019f, 7.2761244052742384f, + 7.2854022188622487f, 7.2946207488916270f, 7.3037807481771031f, + 7.3128829552843557f, 7.3219280948873617f, 7.3309168781146177f, + 7.3398500028846243f, 7.3487281542310781f, 7.3575520046180847f, + 7.3663222142458151f, 7.3750394313469254f, 7.3837042924740528f, + 7.3923174227787607f, 7.4008794362821844f, 7.4093909361377026f, + 7.4178525148858991f, 7.4262647547020979f, 7.4346282276367255f, + 7.4429434958487288f, 7.4512111118323299f, 7.4594316186372973f, + 7.4676055500829976f, 7.4757334309663976f, 7.4838157772642564f, + 7.4918530963296748f, 7.4998458870832057f, 7.5077946401986964f, + 7.5156998382840436f, 7.5235619560570131f, 7.5313814605163119f, + 7.5391588111080319f, 7.5468944598876373f, 7.5545888516776376f, + 7.5622424242210728f, 7.5698556083309478f, 7.5774288280357487f, + 7.5849625007211561f, 7.5924570372680806f, 7.5999128421871278f, + 7.6073303137496113f, 7.6147098441152075f, 7.6220518194563764f, + 7.6293566200796095f, 7.6366246205436488f, 7.6438561897747244f, + 7.6510516911789290f, 7.6582114827517955f, 7.6653359171851765f, + 7.6724253419714952f, 7.6794800995054464f, 7.6865005271832185f, + 7.6934869574993252f, 7.7004397181410926f, 7.7073591320808825f, + 7.7142455176661224f, 7.7210991887071856f, 7.7279204545631996f, + 7.7347096202258392f, 7.7414669864011465f, 7.7481928495894596f, + 7.7548875021634691f, 7.7615512324444795f, 7.7681843247769260f, + 7.7747870596011737f, 7.7813597135246608f, 7.7879025593914317f, + 7.7944158663501062f, 7.8008998999203047f, 7.8073549220576037f, + 7.8137811912170374f, 7.8201789624151887f, 7.8265484872909159f, + 7.8328900141647422f, 7.8392037880969445f, 7.8454900509443757f, + 7.8517490414160571f, 7.8579809951275719f, 7.8641861446542798f, + 7.8703647195834048f, 7.8765169465650002f, 7.8826430493618425f, + 7.8887432488982601f, 7.8948177633079446f, 7.9008668079807496f, + 7.9068905956085187f, 7.9128893362299619f, 7.9188632372745955f, + 7.9248125036057813f, 7.9307373375628867f, 7.9366379390025719f, + 7.9425145053392399f, 7.9483672315846778f, 7.9541963103868758f, + 7.9600019320680806f, 7.9657842846620870f, 7.9715435539507720f, + 7.9772799234999168f, 7.9829935746943104f, 7.9886846867721664f, + 7.9943534368588578f +}; + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/fast_log.h b/packages/runtime/vendor/brotli/c/enc/fast_log.h new file mode 100644 index 000000000..a245443ff --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/fast_log.h @@ -0,0 +1,66 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Utilities for fast computation of logarithms. */ + +#ifndef BROTLI_ENC_FAST_LOG_H_ +#define BROTLI_ENC_FAST_LOG_H_ + +#include + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static BROTLI_INLINE uint32_t Log2FloorNonZero(size_t n) { +#if defined(BROTLI_BSR32) + return BROTLI_BSR32((uint32_t)n); +#else + uint32_t result = 0; + while (n >>= 1) result++; + return result; +#endif +} + +#define BROTLI_LOG2_TABLE_SIZE 256 + +/* A lookup table for small values of log2(int) to be used in entropy + computation. */ +BROTLI_INTERNAL extern const BROTLI_MODEL("small") +double kBrotliLog2Table[BROTLI_LOG2_TABLE_SIZE]; + +/* Visual Studio 2012 and Android API levels < 18 do not have the log2() + * function defined, so we use log() and a multiplication instead. */ +#if !defined(BROTLI_HAVE_LOG2) +#if ((defined(_MSC_VER) && _MSC_VER <= 1700) || \ + (defined(__ANDROID_API__) && __ANDROID_API__ < 18)) +#define BROTLI_HAVE_LOG2 0 +#else +#define BROTLI_HAVE_LOG2 1 +#endif +#endif + +#define LOG_2_INV 1.4426950408889634 + +/* Faster logarithm for small integers, with the property of log2(0) == 0. */ +static BROTLI_INLINE double FastLog2(size_t v) { + if (v < BROTLI_LOG2_TABLE_SIZE) { + return kBrotliLog2Table[v]; + } +#if !(BROTLI_HAVE_LOG2) + return log((double)v) * LOG_2_INV; +#else + return log2((double)v); +#endif +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_FAST_LOG_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/find_match_length.h b/packages/runtime/vendor/brotli/c/enc/find_match_length.h new file mode 100644 index 000000000..096be9331 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/find_match_length.h @@ -0,0 +1,70 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Function to find maximal matching prefixes of strings. */ + +#ifndef BROTLI_ENC_FIND_MATCH_LENGTH_H_ +#define BROTLI_ENC_FIND_MATCH_LENGTH_H_ + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Separate implementation for little-endian 64-bit targets, for speed. */ +#if defined(BROTLI_TZCNT64) && BROTLI_64_BITS && BROTLI_LITTLE_ENDIAN +static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, + const uint8_t* s2, + size_t limit) { + const uint8_t *s1_orig = s1; + for (; limit >= 8; limit -= 8) { + uint64_t x = BROTLI_UNALIGNED_LOAD64LE(s2) ^ + BROTLI_UNALIGNED_LOAD64LE(s1); + s2 += 8; + if (x != 0) { + size_t matching_bits = (size_t)BROTLI_TZCNT64(x); + return (size_t)(s1 - s1_orig) + (matching_bits >> 3); + } + s1 += 8; + } + while (limit && *s1 == *s2) { + limit--; + ++s2; + ++s1; + } + return (size_t)(s1 - s1_orig); +} +#else +static BROTLI_INLINE size_t FindMatchLengthWithLimit(const uint8_t* s1, + const uint8_t* s2, + size_t limit) { + size_t matched = 0; + const uint8_t* s2_limit = s2 + limit; + const uint8_t* s2_ptr = s2; + /* Find out how long the match is. We loop over the data 32 bits at a + time until we find a 32-bit block that doesn't match; then we find + the first non-matching bit and use that to calculate the total + length of the match. */ + while (s2_ptr <= s2_limit - 4 && + BrotliUnalignedRead32(s2_ptr) == + BrotliUnalignedRead32(s1 + matched)) { + s2_ptr += 4; + matched += 4; + } + while ((s2_ptr < s2_limit) && (s1[matched] == *s2_ptr)) { + ++s2_ptr; + ++matched; + } + return matched; +} +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_FIND_MATCH_LENGTH_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/hash.h b/packages/runtime/vendor/brotli/c/enc/hash.h new file mode 100644 index 000000000..d86fa1895 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash.h @@ -0,0 +1,735 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. */ + +#ifndef BROTLI_ENC_HASH_H_ +#define BROTLI_ENC_HASH_H_ + +#include "../common/constants.h" +#include "../common/dictionary.h" +#include "../common/platform.h" +#include "compound_dictionary.h" +#include "encoder_dict.h" +#include "fast_log.h" +#include "find_match_length.h" +#include "hash_base.h" +#include "matching_tag_mask.h" +#include "memory.h" +#include "params.h" +#include "quality.h" +#include "static_dict.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct { + /** + * Dynamically allocated areas; regular hasher uses one or two allocations; + * "composite" hasher uses up to 4 allocations. + */ + void* extra[4]; + + /** + * False before the first invocation of HasherSetup (where "extra" memory) + * is allocated. + */ + BROTLI_BOOL is_setup_; + + size_t dict_num_lookups; + size_t dict_num_matches; + + BrotliHasherParams params; + + /** + * False if hasher needs to be "prepared" before use (before the first + * invocation of HasherSetup or after HasherReset). "preparation" is hasher + * data initialization (using input ringbuffer). + */ + BROTLI_BOOL is_prepared_; +} HasherCommon; + +#define score_t size_t + +static const uint32_t kCutoffTransformsCount = 10; +/* 0, 12, 27, 23, 42, 63, 56, 48, 59, 64 */ +/* 0+0, 4+8, 8+19, 12+11, 16+26, 20+43, 24+32, 28+20, 32+27, 36+28 */ +static const uint64_t kCutoffTransforms = + BROTLI_MAKE_UINT64_T(0x071B520A, 0xDA2D3200); + +typedef struct HasherSearchResult { + size_t len; + size_t distance; + score_t score; + int len_code_delta; /* == len_code - len */ +} HasherSearchResult; + +static BROTLI_INLINE void PrepareDistanceCache( + int* BROTLI_RESTRICT distance_cache, const int num_distances) { + if (num_distances > 4) { + int last_distance = distance_cache[0]; + distance_cache[4] = last_distance - 1; + distance_cache[5] = last_distance + 1; + distance_cache[6] = last_distance - 2; + distance_cache[7] = last_distance + 2; + distance_cache[8] = last_distance - 3; + distance_cache[9] = last_distance + 3; + if (num_distances > 10) { + int next_last_distance = distance_cache[1]; + distance_cache[10] = next_last_distance - 1; + distance_cache[11] = next_last_distance + 1; + distance_cache[12] = next_last_distance - 2; + distance_cache[13] = next_last_distance + 2; + distance_cache[14] = next_last_distance - 3; + distance_cache[15] = next_last_distance + 3; + } + } +} + +#define BROTLI_LITERAL_BYTE_SCORE 135 +#define BROTLI_DISTANCE_BIT_PENALTY 30 +/* Score must be positive after applying maximal penalty. */ +#define BROTLI_SCORE_BASE (BROTLI_DISTANCE_BIT_PENALTY * 8 * sizeof(size_t)) + +/* Usually, we always choose the longest backward reference. This function + allows for the exception of that rule. + + If we choose a backward reference that is further away, it will + usually be coded with more bits. We approximate this by assuming + log2(distance). If the distance can be expressed in terms of the + last four distances, we use some heuristic constants to estimate + the bits cost. For the first up to four literals we use the bit + cost of the literals from the literal cost model, after that we + use the average bit cost of the cost model. + + This function is used to sometimes discard a longer backward reference + when it is not much longer and the bit cost for encoding it is more + than the saved literals. + + backward_reference_offset MUST be positive. */ +static BROTLI_INLINE score_t BackwardReferenceScore( + size_t copy_length, size_t backward_reference_offset) { + return BROTLI_SCORE_BASE + BROTLI_LITERAL_BYTE_SCORE * (score_t)copy_length - + BROTLI_DISTANCE_BIT_PENALTY * Log2FloorNonZero(backward_reference_offset); +} + +static BROTLI_INLINE score_t BackwardReferenceScoreUsingLastDistance( + size_t copy_length) { + return BROTLI_LITERAL_BYTE_SCORE * (score_t)copy_length + + BROTLI_SCORE_BASE + 15; +} + +static BROTLI_INLINE score_t BackwardReferencePenaltyUsingLastDistance( + size_t distance_short_code) { + return (score_t)39 + ((0x1CA10 >> (distance_short_code & 0xE)) & 0xE); +} + +static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem( + const BrotliEncoderDictionary* dictionary, size_t len, size_t word_idx, + const uint8_t* data, size_t max_length, size_t max_backward, + size_t max_distance, HasherSearchResult* out) { + size_t offset; + size_t matchlen; + size_t backward; + score_t score; + offset = dictionary->words->offsets_by_length[len] + len * word_idx; + if (len > max_length) { + return BROTLI_FALSE; + } + + matchlen = + FindMatchLengthWithLimit(data, &dictionary->words->data[offset], len); + if (matchlen + dictionary->cutoffTransformsCount <= len || matchlen == 0) { + return BROTLI_FALSE; + } + { + size_t cut = len - matchlen; + size_t transform_id = (cut << 2) + + (size_t)((dictionary->cutoffTransforms >> (cut * 6)) & 0x3F); + backward = max_backward + 1 + word_idx + + (transform_id << dictionary->words->size_bits_by_length[len]); + } + if (backward > max_distance) { + return BROTLI_FALSE; + } + score = BackwardReferenceScore(matchlen, backward); + if (score < out->score) { + return BROTLI_FALSE; + } + out->len = matchlen; + out->len_code_delta = (int)len - (int)matchlen; + out->distance = backward; + out->score = score; + return BROTLI_TRUE; +} + +static BROTLI_INLINE void SearchInStaticDictionary( + const BrotliEncoderDictionary* dictionary, + HasherCommon* common, const uint8_t* data, size_t max_length, + size_t max_backward, size_t max_distance, + HasherSearchResult* out, BROTLI_BOOL shallow) { + size_t key; + size_t i; + if (common->dict_num_matches < (common->dict_num_lookups >> 7)) { + return; + } + key = Hash14(data) << 1; + for (i = 0; i < (shallow ? 1u : 2u); ++i, ++key) { + common->dict_num_lookups++; + if (dictionary->hash_table_lengths[key] != 0) { + BROTLI_BOOL item_matches = TestStaticDictionaryItem( + dictionary, dictionary->hash_table_lengths[key], + dictionary->hash_table_words[key], data, + max_length, max_backward, max_distance, out); + if (item_matches) { + common->dict_num_matches++; + } + } + } +} + +typedef struct BackwardMatch { + uint32_t distance; + uint32_t length_and_code; +} BackwardMatch; + +static BROTLI_INLINE void InitBackwardMatch(BackwardMatch* self, + size_t dist, size_t len) { + self->distance = (uint32_t)dist; + self->length_and_code = (uint32_t)(len << 5); +} + +static BROTLI_INLINE void InitDictionaryBackwardMatch(BackwardMatch* self, + size_t dist, size_t len, size_t len_code) { + self->distance = (uint32_t)dist; + self->length_and_code = + (uint32_t)((len << 5) | (len == len_code ? 0 : len_code)); +} + +static BROTLI_INLINE size_t BackwardMatchLength(const BackwardMatch* self) { + return self->length_and_code >> 5; +} + +static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) { + size_t code = self->length_and_code & 31; + return code ? code : BackwardMatchLength(self); +} + +#define EXPAND_CAT(a, b) CAT(a, b) +#define CAT(a, b) a ## b +#define FN(X) EXPAND_CAT(X, HASHER()) + +#define HASHER() H10 +#define BUCKET_BITS 17 +#define MAX_TREE_SEARCH_DEPTH 64 +#define MAX_TREE_COMP_LENGTH 128 +#include "hash_to_binary_tree_inc.h" /* NOLINT(build/include) */ +#undef MAX_TREE_SEARCH_DEPTH +#undef MAX_TREE_COMP_LENGTH +#undef BUCKET_BITS +#undef HASHER +/* MAX_NUM_MATCHES == 64 + MAX_TREE_SEARCH_DEPTH */ +#define MAX_NUM_MATCHES_H10 128 + +/* For BUCKET_SWEEP_BITS == 0, enabling the dictionary lookup makes compression + a little faster (0.5% - 1%) and it compresses 0.15% better on small text + and HTML inputs. */ + +#define HASHER() H2 +#define BUCKET_BITS 16 +#define BUCKET_SWEEP_BITS 0 +#define HASH_LEN 5 +#define USE_DICTIONARY 1 +#include "hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */ +#undef BUCKET_SWEEP_BITS +#undef USE_DICTIONARY +#undef HASHER + +#define HASHER() H3 +#define BUCKET_SWEEP_BITS 1 +#define USE_DICTIONARY 0 +#include "hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */ +#undef USE_DICTIONARY +#undef BUCKET_SWEEP_BITS +#undef BUCKET_BITS +#undef HASHER + +#define HASHER() H4 +#define BUCKET_BITS 17 +#define BUCKET_SWEEP_BITS 2 +#define USE_DICTIONARY 1 +#include "hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */ +#undef USE_DICTIONARY +#undef HASH_LEN +#undef BUCKET_SWEEP_BITS +#undef BUCKET_BITS +#undef HASHER + +#define HASHER() H5 +#include "hash_longest_match_inc.h" /* NOLINT(build/include) */ +#undef HASHER + +#define HASHER() H6 +#include "hash_longest_match64_inc.h" /* NOLINT(build/include) */ +#undef HASHER + +#if defined(BROTLI_MAX_SIMD_QUALITY) +#define HASHER() H58 +#include "hash_longest_match_simd_inc.h" /* NOLINT(build/include) */ +#undef HASHER + +#define HASHER() H68 +#include "hash_longest_match64_simd_inc.h" /* NOLINT(build/include) */ +#undef HASHER +#endif + +#define BUCKET_BITS 15 + +#define NUM_LAST_DISTANCES_TO_CHECK 4 +#define NUM_BANKS 1 +#define BANK_BITS 16 +#define HASHER() H40 +#include "hash_forgetful_chain_inc.h" /* NOLINT(build/include) */ +#undef HASHER +#undef NUM_LAST_DISTANCES_TO_CHECK + +#define NUM_LAST_DISTANCES_TO_CHECK 10 +#define HASHER() H41 +#include "hash_forgetful_chain_inc.h" /* NOLINT(build/include) */ +#undef HASHER +#undef NUM_LAST_DISTANCES_TO_CHECK +#undef NUM_BANKS +#undef BANK_BITS + +#define NUM_LAST_DISTANCES_TO_CHECK 16 +#define NUM_BANKS 512 +#define BANK_BITS 9 +#define HASHER() H42 +#include "hash_forgetful_chain_inc.h" /* NOLINT(build/include) */ +#undef HASHER +#undef NUM_LAST_DISTANCES_TO_CHECK +#undef NUM_BANKS +#undef BANK_BITS + +#undef BUCKET_BITS + +#define HASHER() H54 +#define BUCKET_BITS 20 +#define BUCKET_SWEEP_BITS 2 +#define HASH_LEN 7 +#define USE_DICTIONARY 0 +#include "hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */ +#undef USE_DICTIONARY +#undef HASH_LEN +#undef BUCKET_SWEEP_BITS +#undef BUCKET_BITS +#undef HASHER + +/* fast large window hashers */ + +#define HASHER() HROLLING_FAST +#define CHUNKLEN 32 +#define JUMP 4 +#define NUMBUCKETS 16777216 +#define MASK ((NUMBUCKETS * 64) - 1) +#include "hash_rolling_inc.h" /* NOLINT(build/include) */ +#undef JUMP +#undef HASHER + + +#define HASHER() HROLLING +#define JUMP 1 +#include "hash_rolling_inc.h" /* NOLINT(build/include) */ +#undef MASK +#undef NUMBUCKETS +#undef JUMP +#undef CHUNKLEN +#undef HASHER + +#define HASHER() H35 +#define HASHER_A H3 +#define HASHER_B HROLLING_FAST +#include "hash_composite_inc.h" /* NOLINT(build/include) */ +#undef HASHER_A +#undef HASHER_B +#undef HASHER + +#define HASHER() H55 +#define HASHER_A H54 +#define HASHER_B HROLLING_FAST +#include "hash_composite_inc.h" /* NOLINT(build/include) */ +#undef HASHER_A +#undef HASHER_B +#undef HASHER + +#define HASHER() H65 +#define HASHER_A H6 +#define HASHER_B HROLLING +#include "hash_composite_inc.h" /* NOLINT(build/include) */ +#undef HASHER_A +#undef HASHER_B +#undef HASHER + +#undef FN +#undef CAT +#undef EXPAND_CAT + +#if defined(BROTLI_MAX_SIMD_QUALITY) +#define FOR_SIMPLE_HASHERS(H) \ + H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54) H(58) H(68) +#else +#define FOR_SIMPLE_HASHERS(H) \ + H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54) +#endif +#define FOR_COMPOSITE_HASHERS(H) H(35) H(55) H(65) +#define FOR_GENERIC_HASHERS(H) FOR_SIMPLE_HASHERS(H) FOR_COMPOSITE_HASHERS(H) +#define FOR_ALL_HASHERS(H) FOR_GENERIC_HASHERS(H) H(10) + +typedef struct { + HasherCommon common; + + union { +#define MEMBER_(N) \ + H ## N _H ## N; + FOR_ALL_HASHERS(MEMBER_) +#undef MEMBER_ + } privat; +} Hasher; + +/* MUST be invoked before any other method. */ +static BROTLI_INLINE void HasherInit(Hasher* hasher) { + hasher->common.is_setup_ = BROTLI_FALSE; + hasher->common.extra[0] = NULL; + hasher->common.extra[1] = NULL; + hasher->common.extra[2] = NULL; + hasher->common.extra[3] = NULL; +} + +static BROTLI_INLINE void DestroyHasher(MemoryManager* m, Hasher* hasher) { + if (hasher->common.extra[0] != NULL) BROTLI_FREE(m, hasher->common.extra[0]); + if (hasher->common.extra[1] != NULL) BROTLI_FREE(m, hasher->common.extra[1]); + if (hasher->common.extra[2] != NULL) BROTLI_FREE(m, hasher->common.extra[2]); + if (hasher->common.extra[3] != NULL) BROTLI_FREE(m, hasher->common.extra[3]); +} + +static BROTLI_INLINE void HasherReset(Hasher* hasher) { + hasher->common.is_prepared_ = BROTLI_FALSE; +} + +static BROTLI_INLINE void HasherSize(const BrotliEncoderParams* params, + BROTLI_BOOL one_shot, const size_t input_size, size_t* alloc_size) { + switch (params->hasher.type) { +#define SIZE_(N) \ + case N: \ + HashMemAllocInBytesH ## N(params, one_shot, input_size, alloc_size); \ + break; + FOR_ALL_HASHERS(SIZE_) +#undef SIZE_ + default: + break; + } +} + +static BROTLI_INLINE void HasherSetup(MemoryManager* m, Hasher* hasher, + BrotliEncoderParams* params, const uint8_t* data, size_t position, + size_t input_size, BROTLI_BOOL is_last) { + BROTLI_BOOL one_shot = (position == 0 && is_last); + if (!hasher->common.is_setup_) { + size_t alloc_size[4] = {0}; + size_t i; + ChooseHasher(params, ¶ms->hasher); + hasher->common.params = params->hasher; + hasher->common.dict_num_lookups = 0; + hasher->common.dict_num_matches = 0; + HasherSize(params, one_shot, input_size, alloc_size); + for (i = 0; i < 4; ++i) { + if (alloc_size[i] == 0) continue; + hasher->common.extra[i] = BROTLI_ALLOC(m, uint8_t, alloc_size[i]); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(hasher->common.extra[i])) return; + } + switch (hasher->common.params.type) { +#define INITIALIZE_(N) \ + case N: \ + InitializeH ## N(&hasher->common, \ + &hasher->privat._H ## N, params); \ + break; + FOR_ALL_HASHERS(INITIALIZE_); +#undef INITIALIZE_ + default: + break; + } + HasherReset(hasher); + hasher->common.is_setup_ = BROTLI_TRUE; + } + + if (!hasher->common.is_prepared_) { + switch (hasher->common.params.type) { +#define PREPARE_(N) \ + case N: \ + PrepareH ## N( \ + &hasher->privat._H ## N, \ + one_shot, input_size, data); \ + break; + FOR_ALL_HASHERS(PREPARE_) +#undef PREPARE_ + default: break; + } + hasher->common.is_prepared_ = BROTLI_TRUE; + } +} + +static BROTLI_INLINE void InitOrStitchToPreviousBlock( + MemoryManager* m, Hasher* hasher, const uint8_t* data, size_t mask, + BrotliEncoderParams* params, size_t position, size_t input_size, + BROTLI_BOOL is_last) { + HasherSetup(m, hasher, params, data, position, input_size, is_last); + if (BROTLI_IS_OOM(m)) return; + switch (hasher->common.params.type) { +#define INIT_(N) \ + case N: \ + StitchToPreviousBlockH ## N( \ + &hasher->privat._H ## N, \ + input_size, position, data, mask); \ + break; + FOR_ALL_HASHERS(INIT_) +#undef INIT_ + default: break; + } +} + +/* NB: when seamless dictionary-ring-buffer copies are implemented, don't forget + to add proper guards for non-zero-BROTLI_PARAM_STREAM_OFFSET. */ +static BROTLI_INLINE void FindCompoundDictionaryMatch( + const PreparedDictionary* self, const uint8_t* BROTLI_RESTRICT data, + const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, + const size_t cur_ix, const size_t max_length, const size_t distance_offset, + const size_t max_distance, HasherSearchResult* BROTLI_RESTRICT out) { + const uint32_t source_size = self->source_size; + const size_t boundary = distance_offset - source_size; + const uint32_t hash_bits = self->hash_bits; + const uint32_t bucket_bits = self->bucket_bits; + const uint32_t slot_bits = self->slot_bits; + + const uint32_t hash_shift = 64u - bucket_bits; + const uint32_t slot_mask = (~((uint32_t)0U)) >> (32 - slot_bits); + const uint64_t hash_mask = (~((uint64_t)0U)) >> (64 - hash_bits); + + const uint32_t* slot_offsets = (uint32_t*)(&self[1]); + const uint16_t* heads = (uint16_t*)(&slot_offsets[(size_t)1u << slot_bits]); + const uint32_t* items = (uint32_t*)(&heads[(size_t)1u << bucket_bits]); + const uint8_t* source = NULL; + + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + score_t best_score = out->score; + size_t best_len = out->len; + size_t i; + const uint64_t h = + (BROTLI_UNALIGNED_LOAD64LE(&data[cur_ix_masked]) & hash_mask) * + kPreparedDictionaryHashMul64Long; + const uint32_t key = (uint32_t)(h >> hash_shift); + const uint32_t slot = key & slot_mask; + const uint32_t head = heads[key]; + const uint32_t* BROTLI_RESTRICT chain = &items[slot_offsets[slot] + head]; + uint32_t item = (head == 0xFFFF) ? 1 : 0; + + const void* tail = (void*)&items[self->num_items]; + if (self->magic == kPreparedDictionaryMagic) { + source = (const uint8_t*)tail; + } else { + /* kLeanPreparedDictionaryMagic */ + source = (const uint8_t*)BROTLI_UNALIGNED_LOAD_PTR((const uint8_t**)tail); + } + + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + + for (i = 0; i < 4; ++i) { + const size_t distance = (size_t)distance_cache[i]; + size_t offset; + size_t limit; + size_t len; + if (distance <= boundary || distance > distance_offset) continue; + offset = distance_offset - distance; + limit = source_size - offset; + limit = limit > max_length ? max_length : limit; + len = FindMatchLengthWithLimit(&source[offset], &data[cur_ix_masked], + limit); + if (len >= 2) { + score_t score = BackwardReferenceScoreUsingLastDistance(len); + if (best_score < score) { + if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); + if (best_score < score) { + best_score = score; + if (len > best_len) best_len = len; + out->len = len; + out->len_code_delta = 0; + out->distance = distance; + out->score = best_score; + } + } + } + } + /* we require matches of len >4, so increase best_len to 3, so we can compare + * 4 bytes all the time. */ + if (best_len < 3) { + best_len = 3; + } + while (item == 0) { + size_t offset; + size_t distance; + size_t limit; + item = *chain; + chain++; + offset = item & 0x7FFFFFFF; + item &= 0x80000000; + distance = distance_offset - offset; + limit = source_size - offset; + limit = (limit > max_length) ? max_length : limit; + if (distance > max_distance) continue; + if (cur_ix_masked + best_len > ring_buffer_mask || best_len >= limit || + /* compare 4 bytes ending at best_len + 1 */ + BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) != + BrotliUnalignedRead32(&source[offset + best_len - 3])) { + continue; + } + { + const size_t len = FindMatchLengthWithLimit(&source[offset], + &data[cur_ix_masked], + limit); + if (len >= 4) { + score_t score = BackwardReferenceScore(len, distance); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->len_code_delta = 0; + out->distance = distance; + out->score = best_score; + } + } + } + } +} + +/* NB: when seamless dictionary-ring-buffer copies are implemented, don't forget + to add proper guards for non-zero-BROTLI_PARAM_STREAM_OFFSET. */ +static BROTLI_INLINE size_t FindAllCompoundDictionaryMatches( + const PreparedDictionary* self, const uint8_t* BROTLI_RESTRICT data, + const size_t ring_buffer_mask, const size_t cur_ix, const size_t min_length, + const size_t max_length, const size_t distance_offset, + const size_t max_distance, BackwardMatch* matches, size_t match_limit) { + const uint32_t source_size = self->source_size; + const uint32_t hash_bits = self->hash_bits; + const uint32_t bucket_bits = self->bucket_bits; + const uint32_t slot_bits = self->slot_bits; + + const uint32_t hash_shift = 64u - bucket_bits; + const uint32_t slot_mask = (~((uint32_t)0U)) >> (32 - slot_bits); + const uint64_t hash_mask = (~((uint64_t)0U)) >> (64 - hash_bits); + + const uint32_t* slot_offsets = (uint32_t*)(&self[1]); + const uint16_t* heads = (uint16_t*)(&slot_offsets[(size_t)1u << slot_bits]); + const uint32_t* items = (uint32_t*)(&heads[(size_t)1u << bucket_bits]); + const uint8_t* source = NULL; + + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + size_t best_len = min_length; + const uint64_t h = + (BROTLI_UNALIGNED_LOAD64LE(&data[cur_ix_masked]) & hash_mask) * + kPreparedDictionaryHashMul64Long; + const uint32_t key = (uint32_t)(h >> hash_shift); + const uint32_t slot = key & slot_mask; + const uint32_t head = heads[key]; + const uint32_t* BROTLI_RESTRICT chain = &items[slot_offsets[slot] + head]; + uint32_t item = (head == 0xFFFF) ? 1 : 0; + size_t found = 0; + + const void* tail = (void*)&items[self->num_items]; + if (self->magic == kPreparedDictionaryMagic) { + source = (const uint8_t*)tail; + } else { + /* kLeanPreparedDictionaryMagic */ + source = (const uint8_t*)BROTLI_UNALIGNED_LOAD_PTR((const uint8_t**)tail); + } + + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + + while (item == 0) { + size_t offset; + size_t distance; + size_t limit; + size_t len; + item = *chain; + chain++; + offset = item & 0x7FFFFFFF; + item &= 0x80000000; + distance = distance_offset - offset; + limit = source_size - offset; + limit = (limit > max_length) ? max_length : limit; + if (distance > max_distance) continue; + if (cur_ix_masked + best_len > ring_buffer_mask || + best_len >= limit || + data[cur_ix_masked + best_len] != source[offset + best_len]) { + continue; + } + len = FindMatchLengthWithLimit( + &source[offset], &data[cur_ix_masked], limit); + if (len > best_len) { + best_len = len; + InitBackwardMatch(matches++, distance, len); + found++; + if (found == match_limit) break; + } + } + return found; +} + +static BROTLI_INLINE void LookupCompoundDictionaryMatch( + const CompoundDictionary* addon, const uint8_t* BROTLI_RESTRICT data, + const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, + const size_t cur_ix, const size_t max_length, + const size_t max_ring_buffer_distance, const size_t max_distance, + HasherSearchResult* sr) { + size_t base_offset = max_ring_buffer_distance + 1 + addon->total_size - 1; + size_t d; + for (d = 0; d < addon->num_chunks; ++d) { + /* Only one prepared dictionary type is currently supported. */ + FindCompoundDictionaryMatch( + (const PreparedDictionary*)addon->chunks[d], data, ring_buffer_mask, + distance_cache, cur_ix, max_length, + base_offset - addon->chunk_offsets[d], max_distance, sr); + } +} + +static BROTLI_INLINE size_t LookupAllCompoundDictionaryMatches( + const CompoundDictionary* addon, const uint8_t* BROTLI_RESTRICT data, + const size_t ring_buffer_mask, const size_t cur_ix, size_t min_length, + const size_t max_length, const size_t max_ring_buffer_distance, + const size_t max_distance, BackwardMatch* matches, + size_t match_limit) { + size_t base_offset = max_ring_buffer_distance + 1 + addon->total_size - 1; + size_t d; + size_t total_found = 0; + for (d = 0; d < addon->num_chunks; ++d) { + /* Only one prepared dictionary type is currently supported. */ + total_found += FindAllCompoundDictionaryMatches( + (const PreparedDictionary*)addon->chunks[d], data, ring_buffer_mask, + cur_ix, min_length, max_length, base_offset - addon->chunk_offsets[d], + max_distance, matches + total_found, match_limit - total_found); + if (total_found == match_limit) break; + if (total_found > 0) { + min_length = BackwardMatchLength(&matches[total_found - 1]); + } + } + return total_found; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_HASH_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/hash_base.h b/packages/runtime/vendor/brotli/c/enc/hash_base.h new file mode 100644 index 000000000..edf1ef020 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_base.h @@ -0,0 +1,38 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Basic common hash functions / constants. */ + +#ifndef THIRD_PARTY_BROTLI_ENC_HASH_BASE_H_ +#define THIRD_PARTY_BROTLI_ENC_HASH_BASE_H_ + +#include "../common/platform.h" + +/* kHashMul32 multiplier has these properties: + * The multiplier must be odd. Otherwise we may lose the highest bit. + * No long streaks of ones or zeros. + * There is no effort to ensure that it is a prime, the oddity is enough + for this use. + * The number has been tuned heuristically against compression benchmarks. */ +static const uint32_t kHashMul32 = 0x1E35A7BD; +static const uint64_t kHashMul64 = + BROTLI_MAKE_UINT64_T(0x1FE35A7Bu, 0xD3579BD3u); + +static BROTLI_INLINE uint32_t Hash14(const uint8_t* data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - 14); +} + +static BROTLI_INLINE uint32_t Hash15(const uint8_t* data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - 15); +} + +#endif // THIRD_PARTY_BROTLI_ENC_HASH_BASE_H_ diff --git a/packages/runtime/vendor/brotli/c/enc/hash_composite_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_composite_inc.h new file mode 100644 index 000000000..3923bc72c --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_composite_inc.h @@ -0,0 +1,140 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2018 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN, HASHER_A, HASHER_B */ + +/* Composite hasher: This hasher allows to combine two other hashers, HASHER_A + and HASHER_B. */ + +#define HashComposite HASHER() + +#define FN_A(X) EXPAND_CAT(X, HASHER_A) +#define FN_B(X) EXPAND_CAT(X, HASHER_B) + +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { + size_t a = FN_A(HashTypeLength)(); + size_t b = FN_B(HashTypeLength)(); + return a > b ? a : b; +} + +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { + size_t a = FN_A(StoreLookahead)(); + size_t b = FN_B(StoreLookahead)(); + return a > b ? a : b; +} + +typedef struct HashComposite { + HASHER_A ha; + HASHER_B hb; + HasherCommon ha_common; + HasherCommon hb_common; + + /* Shortcuts. */ + HasherCommon* common; + + BROTLI_BOOL fresh; + const BrotliEncoderParams* params; +} HashComposite; + +static void FN(Initialize)(HasherCommon* common, + HashComposite* BROTLI_RESTRICT self, const BrotliEncoderParams* params) { + self->common = common; + + self->ha_common = *self->common; + self->hb_common = *self->common; + self->fresh = BROTLI_TRUE; + self->params = params; + /* TODO(lode): Initialize of the hashers is deferred to Prepare (and params + remembered here) because we don't get the one_shot and input_size params + here that are needed to know the memory size of them. Instead provide + those params to all hashers FN(Initialize) */ +} + +static void FN(Prepare)( + HashComposite* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + if (self->fresh) { + self->fresh = BROTLI_FALSE; + self->ha_common.extra[0] = self->common->extra[0]; + self->ha_common.extra[1] = self->common->extra[1]; + self->ha_common.extra[2] = NULL; + self->ha_common.extra[3] = NULL; + self->hb_common.extra[0] = self->common->extra[2]; + self->hb_common.extra[1] = self->common->extra[3]; + self->hb_common.extra[2] = NULL; + self->hb_common.extra[3] = NULL; + + FN_A(Initialize)(&self->ha_common, &self->ha, self->params); + FN_B(Initialize)(&self->hb_common, &self->hb, self->params); + } + FN_A(Prepare)(&self->ha, one_shot, input_size, data); + FN_B(Prepare)(&self->hb, one_shot, input_size, data); +} + +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + size_t alloc_size_a[4] = {0}; + size_t alloc_size_b[4] = {0}; + FN_A(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_a); + FN_B(HashMemAllocInBytes)(params, one_shot, input_size, alloc_size_b); + /* Should never happen. */ + if (alloc_size_a[2] != 0 || alloc_size_a[3] != 0) exit(EXIT_FAILURE); + if (alloc_size_b[2] != 0 || alloc_size_b[3] != 0) exit(EXIT_FAILURE); + alloc_size[0] = alloc_size_a[0]; + alloc_size[1] = alloc_size_a[1]; + alloc_size[2] = alloc_size_b[0]; + alloc_size[3] = alloc_size_b[1]; +} + +static BROTLI_INLINE void FN(Store)(HashComposite* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { + FN_A(Store)(&self->ha, data, mask, ix); + FN_B(Store)(&self->hb, data, mask, ix); +} + +static BROTLI_INLINE void FN(StoreRange)( + HashComposite* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, + const size_t mask, const size_t ix_start, + const size_t ix_end) { + FN_A(StoreRange)(&self->ha, data, mask, ix_start, ix_end); + FN_B(StoreRange)(&self->hb, data, mask, ix_start, ix_end); +} + +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashComposite* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ring_buffer_mask) { + FN_A(StitchToPreviousBlock)(&self->ha, num_bytes, position, + ringbuffer, ring_buffer_mask); + FN_B(StitchToPreviousBlock)(&self->hb, num_bytes, position, + ringbuffer, ring_buffer_mask); +} + +static BROTLI_INLINE void FN(PrepareDistanceCache)( + HashComposite* BROTLI_RESTRICT self, int* BROTLI_RESTRICT distance_cache) { + FN_A(PrepareDistanceCache)(&self->ha, distance_cache); + FN_B(PrepareDistanceCache)(&self->hb, distance_cache); +} + +static BROTLI_INLINE void FN(FindLongestMatch)( + HashComposite* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, + const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, + const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const size_t max_distance, + HasherSearchResult* BROTLI_RESTRICT out) { + FN_A(FindLongestMatch)(&self->ha, dictionary, data, ring_buffer_mask, + distance_cache, cur_ix, max_length, max_backward, dictionary_distance, + max_distance, out); + FN_B(FindLongestMatch)(&self->hb, dictionary, data, ring_buffer_mask, + distance_cache, cur_ix, max_length, max_backward, dictionary_distance, + max_distance, out); +} + +#undef HashComposite diff --git a/packages/runtime/vendor/brotli/c/enc/hash_forgetful_chain_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_forgetful_chain_inc.h new file mode 100644 index 000000000..c44276fa4 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_forgetful_chain_inc.h @@ -0,0 +1,305 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN, BUCKET_BITS, NUM_BANKS, BANK_BITS, + NUM_LAST_DISTANCES_TO_CHECK */ + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + Hashes are stored in chains which are bucketed to groups. Group of chains + share a storage "bank". When more than "bank size" chain nodes are added, + oldest nodes are replaced; this way several chains may share a tail. */ + +#define HashForgetfulChain HASHER() + +#define BANK_SIZE (1 << BANK_BITS) + +/* Number of hash buckets. */ +#define BUCKET_SIZE (1 << BUCKET_BITS) + +#define CAPPED_CHAINS 0 + +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; } +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; } + +/* HashBytes is the function that chooses the bucket to place the address in.*/ +static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) { + const uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - BUCKET_BITS); +} + +typedef struct FN(Slot) { + uint16_t delta; + uint16_t next; +} FN(Slot); + +typedef struct FN(Bank) { + FN(Slot) slots[BANK_SIZE]; +} FN(Bank); + +typedef struct HashForgetfulChain { + uint16_t free_slot_idx[NUM_BANKS]; /* Up to 1KiB. Move to dynamic? */ + size_t max_hops; + + /* Shortcuts. */ + void* extra[2]; + HasherCommon* common; + + /* --- Dynamic size members --- */ + + /* uint32_t addr[BUCKET_SIZE]; */ + + /* uint16_t head[BUCKET_SIZE]; */ + + /* Truncated hash used for quick rejection of "distance cache" candidates. */ + /* uint8_t tiny_hash[65536];*/ + + /* FN(Bank) banks[NUM_BANKS]; */ +} HashForgetfulChain; + +static uint32_t* FN(Addr)(void* extra) { + return (uint32_t*)extra; +} + +static uint16_t* FN(Head)(void* extra) { + return (uint16_t*)(&FN(Addr)(extra)[BUCKET_SIZE]); +} + +static uint8_t* FN(TinyHash)(void* extra) { + return (uint8_t*)(&FN(Head)(extra)[BUCKET_SIZE]); +} + +static FN(Bank)* FN(Banks)(void* extra) { + return (FN(Bank)*)(extra); +} + +static void FN(Initialize)( + HasherCommon* common, HashForgetfulChain* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common = common; + self->extra[0] = common->extra[0]; + self->extra[1] = common->extra[1]; + + self->max_hops = (params->quality > 6 ? 7u : 8u) << (params->quality - 4); +} + +static void FN(Prepare)( + HashForgetfulChain* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); + uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); + uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra[0]); + /* Partial preparation is 100 times slower (per socket). */ + size_t partial_prepare_threshold = BUCKET_SIZE >> 6; + if (one_shot && input_size <= partial_prepare_threshold) { + size_t i; + for (i = 0; i < input_size; ++i) { + size_t bucket = FN(HashBytes)(&data[i]); + /* See InitEmpty comment. */ + addr[bucket] = 0xCCCCCCCC; + head[bucket] = 0xCCCC; + } + } else { + /* Fill |addr| array with 0xCCCCCCCC value. Because of wrapping, position + processed by hasher never reaches 3GB + 64M; this makes all new chains + to be terminated after the first node. */ + memset(addr, 0xCC, sizeof(uint32_t) * BUCKET_SIZE); + memset(head, 0, sizeof(uint16_t) * BUCKET_SIZE); + } + memset(tiny_hash, 0, sizeof(uint8_t) * 65536); + memset(self->free_slot_idx, 0, sizeof(self->free_slot_idx)); +} + +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + BROTLI_UNUSED(params); + BROTLI_UNUSED(one_shot); + BROTLI_UNUSED(input_size); + alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE + + sizeof(uint16_t) * BUCKET_SIZE + sizeof(uint8_t) * 65536; + alloc_size[1] = sizeof(FN(Bank)) * NUM_BANKS; +} + +/* Look at 4 bytes at &data[ix & mask]. Compute a hash from these, and prepend + node to corresponding chain; also update tiny_hash for current position. */ +static BROTLI_INLINE void FN(Store)(HashForgetfulChain* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { + uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); + uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); + uint8_t* BROTLI_RESTRICT tiny_hash = FN(TinyHash)(self->extra[0]); + FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra[1]); + const size_t key = FN(HashBytes)(&data[ix & mask]); + const size_t bank = key & (NUM_BANKS - 1); + const size_t idx = self->free_slot_idx[bank]++ & (BANK_SIZE - 1); + size_t delta = ix - addr[key]; + tiny_hash[(uint16_t)ix] = (uint8_t)key; + if (delta > 0xFFFF) delta = CAPPED_CHAINS ? 0 : 0xFFFF; + banks[bank].slots[idx].delta = (uint16_t)delta; + banks[bank].slots[idx].next = head[key]; + addr[key] = (uint32_t)ix; + head[key] = (uint16_t)idx; +} + +static BROTLI_INLINE void FN(StoreRange)( + HashForgetfulChain* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + size_t i; + for (i = ix_start; i < ix_end; ++i) { + FN(Store)(self, data, mask, i); + } +} + +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashForgetfulChain* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ring_buffer_mask) { + if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + FN(Store)(self, ringbuffer, ring_buffer_mask, position - 3); + FN(Store)(self, ringbuffer, ring_buffer_mask, position - 2); + FN(Store)(self, ringbuffer, ring_buffer_mask, position - 1); + } +} + +static BROTLI_INLINE void FN(PrepareDistanceCache)( + HashForgetfulChain* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + BROTLI_UNUSED(self); + PrepareDistanceCache(distance_cache, NUM_LAST_DISTANCES_TO_CHECK); +} + +/* Find a longest backward match of &data[cur_ix] up to the length of + max_length and stores the position cur_ix in the hash table. + + REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache + values; if this method is invoked repeatedly with the same distance + cache values, it is enough to invoke FN(PrepareDistanceCache) once. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +static BROTLI_INLINE void FN(FindLongestMatch)( + HashForgetfulChain* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, + const int* BROTLI_RESTRICT distance_cache, + const size_t cur_ix, const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const size_t max_distance, + HasherSearchResult* BROTLI_RESTRICT out) { + uint32_t* BROTLI_RESTRICT addr = FN(Addr)(self->extra[0]); + uint16_t* BROTLI_RESTRICT head = FN(Head)(self->extra[0]); + uint8_t* BROTLI_RESTRICT tiny_hashes = FN(TinyHash)(self->extra[0]); + FN(Bank)* BROTLI_RESTRICT banks = FN(Banks)(self->extra[1]); + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + /* Don't accept a short copy from far away. */ + score_t min_score = out->score; + score_t best_score = out->score; + size_t best_len = out->len; + size_t i; + const size_t key = FN(HashBytes)(&data[cur_ix_masked]); + const uint8_t tiny_hash = (uint8_t)(key); + out->len = 0; + out->len_code_delta = 0; + + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + + /* Try last distance first. */ + for (i = 0; i < NUM_LAST_DISTANCES_TO_CHECK; ++i) { + const size_t backward = (size_t)distance_cache[i]; + size_t prev_ix = (cur_ix - backward); + /* For distance code 0 we want to consider 2-byte matches. */ + if (i > 0 && tiny_hashes[(uint16_t)prev_ix] != tiny_hash) continue; + if (prev_ix >= cur_ix || backward > max_backward) { + continue; + } + prev_ix &= ring_buffer_mask; + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 2) { + score_t score = BackwardReferenceScoreUsingLastDistance(len); + if (best_score < score) { + if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + } + } + /* we require matches of len >4, so increase best_len to 3, so we can compare + * 4 bytes all the time. */ + if (best_len < 3) { + best_len = 3; + } + { + const size_t bank = key & (NUM_BANKS - 1); + size_t backward = 0; + size_t hops = self->max_hops; + size_t delta = cur_ix - addr[key]; + size_t slot = head[key]; + while (hops--) { + size_t prev_ix; + size_t last = slot; + backward += delta; + if (backward > max_backward || (CAPPED_CHAINS && !delta)) break; + prev_ix = (cur_ix - backward) & ring_buffer_mask; + slot = banks[bank].slots[last].next; + delta = banks[bank].slots[last].delta; + if (cur_ix_masked + best_len > ring_buffer_mask || + prev_ix + best_len > ring_buffer_mask || + /* compare 4 bytes ending at best_len + 1 */ + BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) != + BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) { + continue; + } + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 4) { + /* Comparing for >= 3 does not change the semantics, but just saves + for a few unnecessary binary logarithms in backward reference + score, since we are not interested in such short matches. */ + score_t score = BackwardReferenceScore(len, backward); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + } + FN(Store)(self, data, ring_buffer_mask, cur_ix); + } + if (out->score == min_score) { + SearchInStaticDictionary(dictionary, + self->common, &data[cur_ix_masked], max_length, dictionary_distance, + max_distance, out, BROTLI_FALSE); + } +} + +#undef BANK_SIZE +#undef BUCKET_SIZE +#undef CAPPED_CHAINS + +#undef HashForgetfulChain diff --git a/packages/runtime/vendor/brotli/c/enc/hash_longest_match64_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_longest_match64_inc.h new file mode 100644 index 000000000..bdbb30aa5 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_longest_match64_inc.h @@ -0,0 +1,279 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN */ + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + This is a hash map of fixed size (bucket_size_) to a ring buffer of + fixed size (block_size_). The ring buffer contains the last block_size_ + index positions of the given hash key in the compressed data. */ + +#define HashLongestMatch HASHER() + +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; } +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; } + +/* HashBytes is the function that chooses the bucket to place the address in. */ +static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data, + uint64_t hash_mul) { + const uint64_t h = BROTLI_UNALIGNED_LOAD64LE(data) * hash_mul; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return (size_t)(h >> (64 - 15)); +} + +typedef struct HashLongestMatch { + /* Number of hash buckets. */ + size_t bucket_size_; + /* Only block_size_ newest backward references are kept, + and the older are forgotten. */ + size_t block_size_; + /* Hash multiplier tuned to match length. */ + uint64_t hash_mul_; + /* Mask for accessing entries in a block (in a ring-buffer manner). */ + uint32_t block_mask_; + + int block_bits_; + int num_last_distances_to_check_; + + /* Shortcuts. */ + HasherCommon* common_; + + /* --- Dynamic size members --- */ + + /* Number of entries in a particular bucket. */ + uint16_t* num_; /* uint16_t[bucket_size]; */ + + /* Buckets containing block_size_ of backward references. */ + uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */ +} HashLongestMatch; + +static void FN(Initialize)( + HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common_ = common; + + BROTLI_UNUSED(params); + self->hash_mul_ = kHashMul64 << (64 - 5 * 8); + BROTLI_DCHECK(common->params.bucket_bits == 15); + self->bucket_size_ = (size_t)1 << common->params.bucket_bits; + self->block_bits_ = common->params.block_bits; + self->block_size_ = (size_t)1 << common->params.block_bits; + self->block_mask_ = (uint32_t)(self->block_size_ - 1); + self->num_last_distances_to_check_ = + common->params.num_last_distances_to_check; + self->num_ = (uint16_t*)common->extra[0]; + self->buckets_ = (uint32_t*)common->extra[1]; +} + +static void FN(Prepare)( + HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint16_t* BROTLI_RESTRICT num = self->num_; + /* Partial preparation is 100 times slower (per socket). */ + size_t partial_prepare_threshold = self->bucket_size_ >> 6; + if (one_shot && input_size <= partial_prepare_threshold) { + size_t i; + for (i = 0; i < input_size; ++i) { + const size_t key = FN(HashBytes)(&data[i], self->hash_mul_); + num[key] = 0; + } + } else { + memset(num, 0, self->bucket_size_ * sizeof(num[0])); + } +} + +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + size_t bucket_size = (size_t)1 << params->hasher.bucket_bits; + size_t block_size = (size_t)1 << params->hasher.block_bits; + BROTLI_UNUSED(one_shot); + BROTLI_UNUSED(input_size); + alloc_size[0] = sizeof(uint16_t) * bucket_size; + alloc_size[1] = sizeof(uint32_t) * bucket_size * block_size; +} + +/* Look at 4 bytes at &data[ix & mask]. + Compute a hash from these, and store the value of ix at that position. */ +static BROTLI_INLINE void FN(Store)( + HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, + const size_t mask, const size_t ix) { + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + const size_t key = FN(HashBytes)(&data[ix & mask], self->hash_mul_); + const size_t minor_ix = num[key] & self->block_mask_; + const size_t offset = minor_ix + (key << self->block_bits_); + ++num[key]; + buckets[offset] = (uint32_t)ix; +} + +static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + size_t i; + for (i = ix_start; i < ix_end; ++i) { + FN(Store)(self, data, mask, i); + } +} + +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashLongestMatch* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask) { + if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); + } +} + +static BROTLI_INLINE void FN(PrepareDistanceCache)( + HashLongestMatch* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_); +} + +/* Find a longest backward match of &data[cur_ix] up to the length of + max_length and stores the position cur_ix in the hash table. + + REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache + values; if this method is invoked repeatedly with the same distance + cache values, it is enough to invoke FN(PrepareDistanceCache) once. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +static BROTLI_INLINE void FN(FindLongestMatch)( + HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, + const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, + const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const size_t max_distance, + HasherSearchResult* BROTLI_RESTRICT out) { + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + /* Don't accept a short copy from far away. */ + score_t min_score = out->score; + score_t best_score = out->score; + size_t best_len = out->len; + size_t i; + /* Precalculate the hash key and prefetch the bucket. */ + const size_t key = FN(HashBytes)(&data[cur_ix_masked], self->hash_mul_); + uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_]; + PREFETCH_L1(bucket); + if (self->block_bits_ > 4) PREFETCH_L1(bucket + 16); + out->len = 0; + out->len_code_delta = 0; + + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + + /* Try last distance first. */ + for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) { + const size_t backward = (size_t)distance_cache[i]; + size_t prev_ix = (size_t)(cur_ix - backward); + if (prev_ix >= cur_ix) { + continue; + } + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + continue; + } + prev_ix &= ring_buffer_mask; + + if (cur_ix_masked + best_len > ring_buffer_mask) { + break; + } + if (prev_ix + best_len > ring_buffer_mask || + data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { + continue; + } + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 3 || (len == 2 && i < 2)) { + /* Comparing for >= 2 does not change the semantics, but just saves for + a few unnecessary binary logarithms in backward reference score, + since we are not interested in such short matches. */ + score_t score = BackwardReferenceScoreUsingLastDistance(len); + if (best_score < score) { + if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + } + } + /* we require matches of len >4, so increase best_len to 3, so we can compare + * 4 bytes all the time. */ + if (best_len < 3) { + best_len = 3; + } + { + const size_t down = + (num[key] > self->block_size_) ? + (num[key] - self->block_size_) : 0u; + const uint32_t first4 = BrotliUnalignedRead32(data + cur_ix_masked); + const size_t max_length_m4 = max_length - 4; + i = num[key]; + for (; i > down;) { + size_t prev_ix = bucket[--i & self->block_mask_]; + uint32_t current4; + const size_t backward = cur_ix - prev_ix; + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (cur_ix_masked + best_len > ring_buffer_mask) { + break; + } + if (prev_ix + best_len > ring_buffer_mask || + /* compare 4 bytes ending at best_len + 1 */ + BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) != + BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) { + continue; + } + current4 = BrotliUnalignedRead32(data + prev_ix); + if (first4 != current4) continue; + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix + 4], + &data[cur_ix_masked + 4], + max_length_m4) + 4; + const score_t score = BackwardReferenceScore(len, backward); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + bucket[num[key] & self->block_mask_] = (uint32_t)cur_ix; + ++num[key]; + } + if (min_score == out->score) { + SearchInStaticDictionary(dictionary, + self->common_, &data[cur_ix_masked], max_length, dictionary_distance, + max_distance, out, BROTLI_FALSE); + } +} + +#undef HashLongestMatch diff --git a/packages/runtime/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h new file mode 100644 index 000000000..12bd8cffd --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h @@ -0,0 +1,304 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN */ + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + This is a hash map of fixed size (bucket_size_) to a ring buffer of + fixed size (block_size_). The ring buffer contains the last block_size_ + index positions of the given hash key in the compressed data. */ + +#define HashLongestMatch HASHER() + +#define TAG_HASH_BITS 8 +#define TAG_HASH_MASK ((1 << TAG_HASH_BITS) - 1) + +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; } +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; } + +/* HashBytes is the function that chooses the bucket to place the address in. */ +static BROTLI_INLINE size_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data, + uint64_t hash_mul) { + const uint64_t h = BROTLI_UNALIGNED_LOAD64LE(data) * hash_mul; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return (size_t)(h >> (64 - 15 - TAG_HASH_BITS)); +} + +typedef struct HashLongestMatch { + /* Number of hash buckets. */ + size_t bucket_size_; + /* Only block_size_ newest backward references are kept, + and the older are forgotten. */ + size_t block_size_; + /* Hash multiplier tuned to match length. */ + uint64_t hash_mul_; + /* Mask for accessing entries in a block (in a ring-buffer manner). */ + uint32_t block_mask_; + + int block_bits_; + int num_last_distances_to_check_; + + /* Shortcuts. */ + HasherCommon* common_; + + /* --- Dynamic size members --- */ + + /* Number of entries in a particular bucket. */ + uint16_t* num_; /* uint16_t[bucket_size]; */ + + uint8_t* tags_; + + /* Buckets containing block_size_ of backward references. */ + uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */ +} HashLongestMatch; + +static void FN(Initialize)( + HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common_ = common; + + BROTLI_UNUSED(params); + self->hash_mul_ = kHashMul64 << (64 - 5 * 8); + BROTLI_DCHECK(common->params.bucket_bits == 15); + self->bucket_size_ = (size_t)1 << common->params.bucket_bits; + self->block_bits_ = common->params.block_bits; + self->block_size_ = (size_t)1 << common->params.block_bits; + self->block_mask_ = (uint32_t)(self->block_size_ - 1); + self->num_last_distances_to_check_ = + common->params.num_last_distances_to_check; + self->num_ = (uint16_t*)common->extra[0]; + self->tags_ = (uint8_t*)common->extra[1]; + self->buckets_ = (uint32_t*)common->extra[2]; +} + +static void FN(Prepare)( + HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint16_t* BROTLI_RESTRICT num = self->num_; + /* Partial preparation is 100 times slower (per socket). */ + size_t partial_prepare_threshold = self->bucket_size_ >> 6; + if (one_shot && input_size <= partial_prepare_threshold) { + size_t i; + for (i = 0; i < input_size; ++i) { + const size_t hash = FN(HashBytes)(&data[i], self->hash_mul_); + const size_t key = hash >> TAG_HASH_BITS; + num[key] = 65535; + } + } else { + /* Set all the bytes of num to 255, which makes each uint16_t 65535. */ + memset(num, 255, self->bucket_size_ * sizeof(num[0])); + } +} + +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + size_t bucket_size = (size_t)1 << params->hasher.bucket_bits; + size_t block_size = (size_t)1 << params->hasher.block_bits; + BROTLI_UNUSED(one_shot); + BROTLI_UNUSED(input_size); + alloc_size[0] = sizeof(uint16_t) * bucket_size; + alloc_size[1] = sizeof(uint8_t) * bucket_size * block_size; + alloc_size[2] = sizeof(uint32_t) * bucket_size * block_size; +} + +/* Look at 4 bytes at &data[ix & mask]. + Compute a hash from these, and store the value of ix at that position. */ +static BROTLI_INLINE void FN(Store)( + HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, + const size_t mask, const size_t ix) { + uint16_t* BROTLI_RESTRICT num = self->num_; + uint8_t* BROTLI_RESTRICT tags = self->tags_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + const size_t hash = FN(HashBytes)(&data[ix & mask], self->hash_mul_); + const size_t key = hash >> TAG_HASH_BITS; + const uint8_t tag = hash & TAG_HASH_MASK; + const size_t minor_ix = num[key] & self->block_mask_; + const size_t offset = minor_ix + (key << self->block_bits_); + --num[key]; + buckets[offset] = (uint32_t)ix; + tags[offset] = tag; +} + +static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + size_t i; + for (i = ix_start; i < ix_end; ++i) { + FN(Store)(self, data, mask, i); + } +} + +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashLongestMatch* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask) { + if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); + } +} + +static BROTLI_INLINE void FN(PrepareDistanceCache)( + HashLongestMatch* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_); +} + +/* Find a longest backward match of &data[cur_ix] up to the length of + max_length and stores the position cur_ix in the hash table. + + REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache + values; if this method is invoked repeatedly with the same distance + cache values, it is enough to invoke FN(PrepareDistanceCache) once. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +static BROTLI_INLINE void FN(FindLongestMatch)( + HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, + const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, + const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const size_t max_distance, + HasherSearchResult* BROTLI_RESTRICT out) { + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + uint8_t* BROTLI_RESTRICT tags = self->tags_; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + /* Don't accept a short copy from far away. */ + score_t min_score = out->score; + score_t best_score = out->score; + size_t best_len = out->len; + size_t i; + /* Precalculate the hash key and prefetch the bucket. */ + const size_t hash = FN(HashBytes)(&data[cur_ix_masked], self->hash_mul_); + const size_t key = hash >> TAG_HASH_BITS; + uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_]; + uint8_t* BROTLI_RESTRICT tag_bucket = &tags[key << self->block_bits_]; + PREFETCH_L1(bucket); + PREFETCH_L1(tag_bucket); + if (self->block_bits_ > 4) PREFETCH_L1(bucket + 16); + out->len = 0; + out->len_code_delta = 0; + + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + + /* Try last distance first. */ + for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) { + const size_t backward = (size_t)distance_cache[i]; + size_t prev_ix = (size_t)(cur_ix - backward); + if (prev_ix >= cur_ix) { + continue; + } + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + continue; + } + prev_ix &= ring_buffer_mask; + + if (cur_ix_masked + best_len > ring_buffer_mask) { + break; + } + if (prev_ix + best_len > ring_buffer_mask || + data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { + continue; + } + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 3 || (len == 2 && i < 2)) { + /* Comparing for >= 2 does not change the semantics, but just saves for + a few unnecessary binary logarithms in backward reference score, + since we are not interested in such short matches. */ + score_t score = BackwardReferenceScoreUsingLastDistance(len); + if (best_score < score) { + if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + } + } + /* we require matches of len >4, so increase best_len to 3, so we can compare + * 4 bytes all the time. */ + if (best_len < 3) { + best_len = 3; + } + { + const uint8_t tag = hash & TAG_HASH_MASK; + const uint32_t first4 = BrotliUnalignedRead32(data + cur_ix_masked); + const size_t max_length_m4 = max_length - 4; + const size_t head = (num[key] + 1) & self->block_mask_; + uint64_t matches = + GetMatchingTagMask(self->block_size_ / 16, tag, tag_bucket, head); + /* Mask off any matches from uninitialized tags. */ + uint16_t n = 65535 - num[key]; + uint64_t block_has_unused_slots = self->block_size_ > n; + uint64_t mask = (block_has_unused_slots << (n & (64 - 1))) - 1; + matches &= mask; + for (; matches > 0; matches &= (matches - 1)) { + const size_t rb_index = + (head + (size_t)BROTLI_TZCNT64(matches)) & self->block_mask_; + size_t prev_ix = bucket[rb_index]; + uint32_t current4; + const size_t backward = cur_ix - prev_ix; + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (cur_ix_masked + best_len > ring_buffer_mask) { + break; + } + if (prev_ix + best_len > ring_buffer_mask || + /* compare 4 bytes ending at best_len + 1 */ + BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) != + BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) { + continue; + } + current4 = BrotliUnalignedRead32(data + prev_ix); + if (first4 != current4) continue; + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix + 4], + &data[cur_ix_masked + 4], + max_length_m4) + 4; + const score_t score = BackwardReferenceScore(len, backward); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + bucket[num[key] & self->block_mask_] = (uint32_t)cur_ix; + tag_bucket[num[key] & self->block_mask_] = tag; + --num[key]; + } + if (min_score == out->score) { + SearchInStaticDictionary(dictionary, + self->common_, &data[cur_ix_masked], max_length, dictionary_distance, + max_distance, out, BROTLI_FALSE); + } +} + +#undef HashLongestMatch diff --git a/packages/runtime/vendor/brotli/c/enc/hash_longest_match_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_longest_match_inc.h new file mode 100644 index 000000000..58e88b3a6 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_longest_match_inc.h @@ -0,0 +1,277 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN */ + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + This is a hash map of fixed size (bucket_size_) to a ring buffer of + fixed size (block_size_). The ring buffer contains the last block_size_ + index positions of the given hash key in the compressed data. */ + +#define HashLongestMatch HASHER() + +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; } +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; } + +/* HashBytes is the function that chooses the bucket to place the address in. */ +static uint32_t FN(HashBytes)( + const uint8_t* BROTLI_RESTRICT data, const int shift) { + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return (uint32_t)(h >> shift); +} + +typedef struct HashLongestMatch { + /* Number of hash buckets. */ + size_t bucket_size_; + /* Only block_size_ newest backward references are kept, + and the older are forgotten. */ + size_t block_size_; + /* Left-shift for computing hash bucket index from hash value. */ + int hash_shift_; + /* Mask for accessing entries in a block (in a ring-buffer manner). */ + uint32_t block_mask_; + + int block_bits_; + int num_last_distances_to_check_; + + /* Shortcuts. */ + HasherCommon* common_; + + /* --- Dynamic size members --- */ + + /* Number of entries in a particular bucket. */ + uint16_t* num_; /* uint16_t[bucket_size]; */ + + /* Buckets containing block_size_ of backward references. */ + uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */ +} HashLongestMatch; + +static void FN(Initialize)( + HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common_ = common; + + BROTLI_UNUSED(params); + self->hash_shift_ = 32 - common->params.bucket_bits; + self->bucket_size_ = (size_t)1 << common->params.bucket_bits; + self->block_size_ = (size_t)1 << common->params.block_bits; + self->block_mask_ = (uint32_t)(self->block_size_ - 1); + self->num_ = (uint16_t*)common->extra[0]; + self->buckets_ = (uint32_t*)common->extra[1]; + self->block_bits_ = common->params.block_bits; + self->num_last_distances_to_check_ = + common->params.num_last_distances_to_check; +} + +static void FN(Prepare)( + HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint16_t* BROTLI_RESTRICT num = self->num_; + /* Partial preparation is 100 times slower (per socket). */ + size_t partial_prepare_threshold = self->bucket_size_ >> 6; + if (one_shot && input_size <= partial_prepare_threshold) { + size_t i; + for (i = 0; i < input_size; ++i) { + const uint32_t key = FN(HashBytes)(&data[i], self->hash_shift_); + num[key] = 0; + } + } else { + memset(num, 0, self->bucket_size_ * sizeof(num[0])); + } +} + +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + size_t bucket_size = (size_t)1 << params->hasher.bucket_bits; + size_t block_size = (size_t)1 << params->hasher.block_bits; + BROTLI_UNUSED(one_shot); + BROTLI_UNUSED(input_size); + alloc_size[0] = sizeof(uint16_t) * bucket_size; + alloc_size[1] = sizeof(uint32_t) * bucket_size * block_size; +} + +/* Look at 4 bytes at &data[ix & mask]. + Compute a hash from these, and store the value of ix at that position. */ +static BROTLI_INLINE void FN(Store)( + HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, + const size_t mask, const size_t ix) { + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + const uint32_t key = FN(HashBytes)(&data[ix & mask], self->hash_shift_); + const size_t minor_ix = num[key] & self->block_mask_; + const size_t offset = minor_ix + (key << self->block_bits_); + ++num[key]; + buckets[offset] = (uint32_t)ix; +} + +static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + size_t i; + for (i = ix_start; i < ix_end; ++i) { + FN(Store)(self, data, mask, i); + } +} + +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashLongestMatch* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask) { + if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); + } +} + +static BROTLI_INLINE void FN(PrepareDistanceCache)( + HashLongestMatch* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_); +} + +/* Find a longest backward match of &data[cur_ix] up to the length of + max_length and stores the position cur_ix in the hash table. + + REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache + values; if this method is invoked repeatedly with the same distance + cache values, it is enough to invoke FN(PrepareDistanceCache) once. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +static BROTLI_INLINE void FN(FindLongestMatch)( + HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, + const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, + const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const size_t max_distance, + HasherSearchResult* BROTLI_RESTRICT out) { + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + /* Don't accept a short copy from far away. */ + score_t min_score = out->score; + score_t best_score = out->score; + size_t best_len = out->len; + size_t i; + /* Precalculate the hash key and prefetch the bucket. */ + const uint32_t key = + FN(HashBytes)(&data[cur_ix_masked], self->hash_shift_); + uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_]; + PREFETCH_L1(bucket); + if (self->block_bits_ > 4) PREFETCH_L1(bucket + 16); + out->len = 0; + out->len_code_delta = 0; + + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + + /* Try last distance first. */ + for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) { + const size_t backward = (size_t)distance_cache[i]; + size_t prev_ix = (size_t)(cur_ix - backward); + if (prev_ix >= cur_ix) { + continue; + } + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + continue; + } + prev_ix &= ring_buffer_mask; + + if (cur_ix_masked + best_len > ring_buffer_mask) { + break; + } + if (prev_ix + best_len > ring_buffer_mask || + data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { + continue; + } + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 3 || (len == 2 && i < 2)) { + /* Comparing for >= 2 does not change the semantics, but just saves for + a few unnecessary binary logarithms in backward reference score, + since we are not interested in such short matches. */ + score_t score = BackwardReferenceScoreUsingLastDistance(len); + if (best_score < score) { + if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + } + } + /* we require matches of len >4, so increase best_len to 3, so we can compare + * 4 bytes all the time. */ + if (best_len < 3) { + best_len = 3; + } + { + const size_t down = + (num[key] > self->block_size_) ? (num[key] - self->block_size_) : 0u; + for (i = num[key]; i > down;) { + size_t prev_ix = bucket[--i & self->block_mask_]; + const size_t backward = cur_ix - prev_ix; + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (cur_ix_masked + best_len > ring_buffer_mask) { + break; + } + if (prev_ix + best_len > ring_buffer_mask || + /* compare 4 bytes ending at best_len + 1 */ + BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) != + BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) { + continue; + } + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 4) { + /* Comparing for >= 3 does not change the semantics, but just saves + for a few unnecessary binary logarithms in backward reference + score, since we are not interested in such short matches. */ + score_t score = BackwardReferenceScore(len, backward); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + } + bucket[num[key] & self->block_mask_] = (uint32_t)cur_ix; + ++num[key]; + } + if (min_score == out->score) { + SearchInStaticDictionary(dictionary, + self->common_, &data[cur_ix_masked], max_length, dictionary_distance, + max_distance, out, BROTLI_FALSE); + } +} + +#undef HashLongestMatch diff --git a/packages/runtime/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h new file mode 100644 index 000000000..57ed586fe --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h @@ -0,0 +1,270 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN, BUCKET_BITS, BUCKET_SWEEP_BITS, HASH_LEN, + USE_DICTIONARY + */ + +#define HashLongestMatchQuickly HASHER() + +#define BUCKET_SIZE (1 << BUCKET_BITS) +#define BUCKET_MASK (BUCKET_SIZE - 1) +#define BUCKET_SWEEP (1 << BUCKET_SWEEP_BITS) +#define BUCKET_SWEEP_MASK ((BUCKET_SWEEP - 1) << 3) + +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 8; } +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 8; } + +/* HashBytes is the function that chooses the bucket to place + the address in. The HashLongestMatch and HashLongestMatchQuickly + classes have separate, different implementations of hashing. */ +static uint32_t FN(HashBytes)(const uint8_t* data) { + const uint64_t h = ((BROTLI_UNALIGNED_LOAD64LE(data) << (64 - 8 * HASH_LEN)) * + kHashMul64); + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return (uint32_t)(h >> (64 - BUCKET_BITS)); +} + +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + + This is a hash map of fixed size (BUCKET_SIZE). */ +typedef struct HashLongestMatchQuickly { + /* Shortcuts. */ + HasherCommon* common; + + /* --- Dynamic size members --- */ + + uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ +} HashLongestMatchQuickly; + +static void FN(Initialize)( + HasherCommon* common, HashLongestMatchQuickly* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common = common; + + BROTLI_UNUSED(params); + self->buckets_ = (uint32_t*)common->extra[0]; +} + +static void FN(Prepare)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + /* Partial preparation is 100 times slower (per socket). */ + size_t partial_prepare_threshold = BUCKET_SIZE >> 5; + if (one_shot && input_size <= partial_prepare_threshold) { + size_t i; + for (i = 0; i < input_size; ++i) { + const uint32_t key = FN(HashBytes)(&data[i]); + if (BUCKET_SWEEP == 1) { + buckets[key] = 0; + } else { + uint32_t j; + for (j = 0; j < BUCKET_SWEEP; ++j) { + buckets[(key + (j << 3)) & BUCKET_MASK] = 0; + } + } + } + } else { + /* It is not strictly necessary to fill this buffer here, but + not filling will make the results of the compression stochastic + (but correct). This is because random data would cause the + system to find accidentally good backward references here and there. */ + memset(buckets, 0, sizeof(uint32_t) * BUCKET_SIZE); + } +} + +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + BROTLI_UNUSED(params); + BROTLI_UNUSED(one_shot); + BROTLI_UNUSED(input_size); + alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE; +} + +/* Look at 5 bytes at &data[ix & mask]. + Compute a hash from these, and store the value somewhere within + [ix .. ix+3]. */ +static BROTLI_INLINE void FN(Store)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { + const uint32_t key = FN(HashBytes)(&data[ix & mask]); + if (BUCKET_SWEEP == 1) { + self->buckets_[key] = (uint32_t)ix; + } else { + /* Wiggle the value with the bucket sweep range. */ + const uint32_t off = ix & BUCKET_SWEEP_MASK; + self->buckets_[(key + off) & BUCKET_MASK] = (uint32_t)ix; + } +} + +static BROTLI_INLINE void FN(StoreRange)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + size_t i; + for (i = ix_start; i < ix_end; ++i) { + FN(Store)(self, data, mask, i); + } +} + +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, + const uint8_t* ringbuffer, size_t ringbuffer_mask) { + if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); + } +} + +static BROTLI_INLINE void FN(PrepareDistanceCache)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + BROTLI_UNUSED(self); + BROTLI_UNUSED(distance_cache); +} + +/* Find a longest backward match of &data[cur_ix & ring_buffer_mask] + up to the length of max_length and stores the position cur_ix in the + hash table. + + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +static BROTLI_INLINE void FN(FindLongestMatch)( + HashLongestMatchQuickly* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, + const size_t ring_buffer_mask, const int* BROTLI_RESTRICT distance_cache, + const size_t cur_ix, const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const size_t max_distance, + HasherSearchResult* BROTLI_RESTRICT out) { + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + const size_t best_len_in = out->len; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + /* TODO: compare 4 bytes at once (and set the minimum best len to 4) */ + int compare_char = data[cur_ix_masked + best_len_in]; + size_t key = FN(HashBytes)(&data[cur_ix_masked]); + size_t key_out; + score_t min_score = out->score; + score_t best_score = out->score; + size_t best_len = best_len_in; + size_t cached_backward = (size_t)distance_cache[0]; + size_t prev_ix = cur_ix - cached_backward; + + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + + out->len_code_delta = 0; + if (prev_ix < cur_ix) { + prev_ix &= (uint32_t)ring_buffer_mask; + if (compare_char == data[prev_ix + best_len]) { + const size_t len = FindMatchLengthWithLimit( + &data[prev_ix], &data[cur_ix_masked], max_length); + if (len >= 4) { + const score_t score = BackwardReferenceScoreUsingLastDistance(len); + if (best_score < score) { + out->len = len; + out->distance = cached_backward; + out->score = score; + if (BUCKET_SWEEP == 1) { + buckets[key] = (uint32_t)cur_ix; + return; + } else { + best_len = len; + best_score = score; + compare_char = data[cur_ix_masked + len]; + } + } + } + } + } + if (BUCKET_SWEEP == 1) { + size_t backward; + size_t len; + /* Only one to look for, don't bother to prepare for a loop. */ + prev_ix = buckets[key]; + buckets[key] = (uint32_t)cur_ix; + backward = cur_ix - prev_ix; + prev_ix &= (uint32_t)ring_buffer_mask; + if (compare_char != data[prev_ix + best_len_in]) { + return; + } + if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { + return; + } + len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 4) { + const score_t score = BackwardReferenceScore(len, backward); + if (best_score < score) { + out->len = len; + out->distance = backward; + out->score = score; + return; + } + } + } else { + size_t keys[BUCKET_SWEEP]; + size_t i; + for (i = 0; i < BUCKET_SWEEP; ++i) { + keys[i] = (key + (i << 3)) & BUCKET_MASK; + } + key_out = keys[(cur_ix & BUCKET_SWEEP_MASK) >> 3]; + for (i = 0; i < BUCKET_SWEEP; ++i) { + size_t len; + size_t backward; + prev_ix = buckets[keys[i]]; + backward = cur_ix - prev_ix; + prev_ix &= (uint32_t)ring_buffer_mask; + if (compare_char != data[prev_ix + best_len]) { + continue; + } + if (BROTLI_PREDICT_FALSE(backward == 0 || backward > max_backward)) { + continue; + } + len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 4) { + const score_t score = BackwardReferenceScore(len, backward); + if (best_score < score) { + best_len = len; + out->len = len; + compare_char = data[cur_ix_masked + len]; + best_score = score; + out->score = score; + out->distance = backward; + } + } + } + } + if (USE_DICTIONARY && min_score == out->score) { + SearchInStaticDictionary(dictionary, + self->common, &data[cur_ix_masked], max_length, dictionary_distance, + max_distance, out, BROTLI_TRUE); + } + if (BUCKET_SWEEP != 1) { + buckets[key_out] = (uint32_t)cur_ix; + } +} + +#undef BUCKET_SWEEP_MASK +#undef BUCKET_SWEEP +#undef BUCKET_MASK +#undef BUCKET_SIZE + +#undef HashLongestMatchQuickly diff --git a/packages/runtime/vendor/brotli/c/enc/hash_longest_match_simd_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_longest_match_simd_inc.h new file mode 100644 index 000000000..79b341ae5 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_longest_match_simd_inc.h @@ -0,0 +1,278 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2010 Google Inc. All Rights Reserved. + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ +/* template parameters: FN */ +/* A (forgetful) hash table to the data seen by the compressor, to + help create backward references to previous data. + This is a hash map of fixed size (bucket_size_) to a ring buffer of + fixed size (block_size_). The ring buffer contains the last block_size_ + index positions of the given hash key in the compressed data. */ +#define HashLongestMatch HASHER() +#define TAG_HASH_BITS 8 +#define TAG_HASH_MASK ((1 << TAG_HASH_BITS) - 1) +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; } +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; } +/* HashBytes is the function that chooses the bucket to place the address in. */ +static uint32_t FN(HashBytes)( + const uint8_t* BROTLI_RESTRICT data, const int shift) { + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return (uint32_t)(h >> shift); +} +typedef struct HashLongestMatch { + /* Number of hash buckets. */ + size_t bucket_size_; + /* Only block_size_ newest backward references are kept, + and the older are forgotten. */ + size_t block_size_; + /* Left-shift for computing hash bucket index from hash value. */ + int hash_shift_; + /* Mask for accessing entries in a block (in a ring-buffer manner). */ + uint32_t block_mask_; + int block_bits_; + int num_last_distances_to_check_; + /* Shortcuts. */ + HasherCommon* common_; + /* --- Dynamic size members --- */ + /* Number of entries in a particular bucket. */ + uint16_t* num_; /* uint16_t[bucket_size]; */ + uint8_t* tags_; + /* Buckets containing block_size_ of backward references. */ + uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */ +} HashLongestMatch; +static void FN(Initialize)( + HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->common_ = common; + BROTLI_UNUSED(params); + self->hash_shift_ = 32 - common->params.bucket_bits - TAG_HASH_BITS; + self->bucket_size_ = (size_t)1 << common->params.bucket_bits; + self->block_size_ = (size_t)1 << common->params.block_bits; + self->block_mask_ = (uint32_t)(self->block_size_ - 1); + self->num_ = (uint16_t*)common->extra[0]; + self->tags_ = (uint8_t*)common->extra[1]; + self->buckets_ = (uint32_t*)common->extra[2]; + self->block_bits_ = common->params.block_bits; + self->num_last_distances_to_check_ = + common->params.num_last_distances_to_check; +} +static void FN(Prepare)( + HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint16_t* BROTLI_RESTRICT num = self->num_; + /* Partial preparation is 100 times slower (per socket). */ + size_t partial_prepare_threshold = self->bucket_size_ >> 6; + if (one_shot && input_size <= partial_prepare_threshold) { + size_t i; + for (i = 0; i < input_size; ++i) { + const uint32_t hash = FN(HashBytes)(&data[i], self->hash_shift_); + const uint32_t key = hash >> TAG_HASH_BITS; + num[key] = 65535; + } + } else { + /* Set all the bytes of num to 255, which makes each uint16_t 65535. */ + memset(num, 255, self->bucket_size_ * sizeof(num[0])); + } +} +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + size_t bucket_size = (size_t)1 << params->hasher.bucket_bits; + size_t block_size = (size_t)1 << params->hasher.block_bits; + BROTLI_UNUSED(one_shot); + BROTLI_UNUSED(input_size); + alloc_size[0] = sizeof(uint16_t) * bucket_size; + alloc_size[1] = sizeof(uint8_t) * bucket_size * block_size; + alloc_size[2] = sizeof(uint32_t) * bucket_size * block_size; +} +/* Look at 4 bytes at &data[ix & mask]. + Compute a hash from these, and store the value of ix at that position. */ +static BROTLI_INLINE void FN(Store)( + HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, + const size_t mask, const size_t ix) { + uint16_t* BROTLI_RESTRICT num = self->num_; + uint8_t* BROTLI_RESTRICT tags = self->tags_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + const size_t hash = FN(HashBytes)(&data[ix & mask], self->hash_shift_); + const size_t key = hash >> TAG_HASH_BITS; + const uint8_t tag = hash & TAG_HASH_MASK; + const size_t minor_ix = num[key] & self->block_mask_; + const size_t offset = minor_ix + (key << self->block_bits_); + --num[key]; + buckets[offset] = (uint32_t)ix; + tags[offset] = tag; +} +static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + size_t i; + for (i = ix_start; i < ix_end; ++i) { + FN(Store)(self, data, mask, i); + } +} +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashLongestMatch* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask) { + if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) { + /* Prepare the hashes for three last bytes of the last write. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2); + FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1); + } +} +static BROTLI_INLINE void FN(PrepareDistanceCache)( + HashLongestMatch* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_); +} + +/* Find a longest backward match of &data[cur_ix] up to the length of + max_length and stores the position cur_ix in the hash table. + REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache + values; if this method is invoked repeatedly with the same distance + cache values, it is enough to invoke FN(PrepareDistanceCache) once. + Does not look for matches longer than max_length. + Does not look for matches further away than max_backward. + Writes the best match into |out|. + |out|->score is updated only if a better match is found. */ +static BROTLI_INLINE void FN(FindLongestMatch)( + HashLongestMatch* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, + const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, + const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const size_t max_distance, + HasherSearchResult* BROTLI_RESTRICT out) { + uint16_t* BROTLI_RESTRICT num = self->num_; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + uint8_t* BROTLI_RESTRICT tags = self->tags_; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + /* Don't accept a short copy from far away. */ + score_t min_score = out->score; + score_t best_score = out->score; + size_t best_len = out->len; + size_t i; + /* Precalculate the hash key and prefetch the bucket. */ + const uint32_t hash = + FN(HashBytes)(&data[cur_ix_masked], self->hash_shift_); + const uint32_t key = hash >> TAG_HASH_BITS; + uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_]; + uint8_t* BROTLI_RESTRICT tag_bucket = &tags[key << self->block_bits_]; + PREFETCH_L1(bucket); + PREFETCH_L1(tag_bucket); + if (self->block_bits_ > 4) PREFETCH_L1(bucket + 16); + out->len = 0; + out->len_code_delta = 0; + + BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask); + + /* Try last distance first. */ + for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) { + const size_t backward = (size_t)distance_cache[i]; + size_t prev_ix = (size_t)(cur_ix - backward); + if (prev_ix >= cur_ix) { + continue; + } + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + continue; + } + prev_ix &= ring_buffer_mask; + + if (cur_ix_masked + best_len > ring_buffer_mask) { + break; + } + if (prev_ix + best_len > ring_buffer_mask || + data[cur_ix_masked + best_len] != data[prev_ix + best_len]) { + continue; + } + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 3 || (len == 2 && i < 2)) { + /* Comparing for >= 2 does not change the semantics, but just saves for + a few unnecessary binary logarithms in backward reference score, + since we are not interested in such short matches. */ + score_t score = BackwardReferenceScoreUsingLastDistance(len); + if (best_score < score) { + if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + } + } + /* we require matches of len >4, so increase best_len to 3, so we can compare + * 4 bytes all the time. */ + if (best_len < 3) { + best_len = 3; + } + { + const uint8_t tag = hash & TAG_HASH_MASK; + const size_t head = (num[key] + 1) & self->block_mask_; + uint64_t matches = + GetMatchingTagMask(self->block_size_ / 16, tag, tag_bucket, head); + /* Mask off any matches from uninitialized tags. */ + uint16_t n = 65535 - num[key]; + uint64_t block_has_unused_slots = self->block_size_ > n; + uint64_t mask = (block_has_unused_slots << (n & (64 - 1))) - 1; + matches &= mask; + for (; matches > 0; matches &= (matches - 1)) { + const size_t rb_index = + (head + (size_t)BROTLI_TZCNT64(matches)) & self->block_mask_; + size_t prev_ix = bucket[rb_index]; + const size_t backward = cur_ix - prev_ix; + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (cur_ix_masked + best_len > ring_buffer_mask) { + break; + } + if (prev_ix + best_len > ring_buffer_mask || + /* compare 4 bytes ending at best_len + 1 */ + BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) != + BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) { + continue; + } + { + const size_t len = FindMatchLengthWithLimit(&data[prev_ix], + &data[cur_ix_masked], + max_length); + if (len >= 4) { + /* Comparing for >= 3 does not change the semantics, but just saves + for a few unnecessary binary logarithms in backward reference + score, since we are not interested in such short matches. */ + score_t score = BackwardReferenceScore(len, backward); + if (best_score < score) { + best_score = score; + best_len = len; + out->len = best_len; + out->distance = backward; + out->score = best_score; + } + } + } + } + bucket[num[key] & self->block_mask_] = (uint32_t)cur_ix; + tag_bucket[num[key] & self->block_mask_] = tag; + --num[key]; + } + if (min_score == out->score) { + SearchInStaticDictionary(dictionary, + self->common_, &data[cur_ix_masked], max_length, dictionary_distance, + max_distance, out, BROTLI_FALSE); + } +} +#undef HashLongestMatch diff --git a/packages/runtime/vendor/brotli/c/enc/hash_rolling_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_rolling_inc.h new file mode 100644 index 000000000..4c7a6b199 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_rolling_inc.h @@ -0,0 +1,212 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2018 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN, JUMP, NUMBUCKETS, MASK, CHUNKLEN */ +/* NUMBUCKETS / (MASK + 1) = probability of storing and using hash code. */ +/* JUMP = skip bytes for speedup */ + +/* Rolling hash for long distance long string matches. Stores one position + per bucket, bucket key is computed over a long region. */ + +#define HashRolling HASHER() + +static const uint32_t FN(kRollingHashMul32) = 69069; +static const uint32_t FN(kInvalidPos) = 0xffffffff; + +/* This hasher uses a longer forward length, but returning a higher value here + will hurt compression by the main hasher when combined with a composite + hasher. The hasher tests for forward itself instead. */ +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; } +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; } + +/* Computes a code from a single byte. A lookup table of 256 values could be + used, but simply adding 1 works about as good. */ +static uint32_t FN(HashByte)(uint8_t byte) { + return (uint32_t)byte + 1u; +} + +static uint32_t FN(HashRollingFunctionInitial)(uint32_t state, uint8_t add, + uint32_t factor) { + return (uint32_t)(factor * state + FN(HashByte)(add)); +} + +static uint32_t FN(HashRollingFunction)(uint32_t state, uint8_t add, + uint8_t rem, uint32_t factor, + uint32_t factor_remove) { + return (uint32_t)(factor * state + + FN(HashByte)(add) - factor_remove * FN(HashByte)(rem)); +} + +typedef struct HashRolling { + uint32_t state; + uint32_t* table; + size_t next_ix; + + uint32_t chunk_len; + uint32_t factor; + uint32_t factor_remove; +} HashRolling; + +static void FN(Initialize)( + HasherCommon* common, HashRolling* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + size_t i; + self->state = 0; + self->next_ix = 0; + + self->factor = FN(kRollingHashMul32); + + /* Compute the factor of the oldest byte to remove: factor**steps modulo + 0xffffffff (the multiplications rely on 32-bit overflow) */ + self->factor_remove = 1; + for (i = 0; i < CHUNKLEN; i += JUMP) { + self->factor_remove *= self->factor; + } + + self->table = (uint32_t*)common->extra[0]; + for (i = 0; i < NUMBUCKETS; i++) { + self->table[i] = FN(kInvalidPos); + } + + BROTLI_UNUSED(params); +} + +static void FN(Prepare)(HashRolling* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + size_t i; + /* Too small size, cannot use this hasher. */ + if (input_size < CHUNKLEN) return; + self->state = 0; + for (i = 0; i < CHUNKLEN; i += JUMP) { + self->state = FN(HashRollingFunctionInitial)( + self->state, data[i], self->factor); + } + BROTLI_UNUSED(one_shot); +} + +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + BROTLI_UNUSED(params); + BROTLI_UNUSED(one_shot); + BROTLI_UNUSED(input_size); + alloc_size[0] = NUMBUCKETS * sizeof(uint32_t); +} + +static BROTLI_INLINE void FN(Store)(HashRolling* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, const size_t ix) { + BROTLI_UNUSED(self); + BROTLI_UNUSED(data); + BROTLI_UNUSED(mask); + BROTLI_UNUSED(ix); +} + +static BROTLI_INLINE void FN(StoreRange)(HashRolling* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + BROTLI_UNUSED(self); + BROTLI_UNUSED(data); + BROTLI_UNUSED(mask); + BROTLI_UNUSED(ix_start); + BROTLI_UNUSED(ix_end); +} + +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashRolling* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ring_buffer_mask) { + /* In this case we must re-initialize the hasher from scratch from the + current position. */ + size_t position_masked; + size_t available = num_bytes; + if ((position & (JUMP - 1)) != 0) { + size_t diff = JUMP - (position & (JUMP - 1)); + available = (diff > available) ? 0 : (available - diff); + position += diff; + } + position_masked = position & ring_buffer_mask; + /* wrapping around ringbuffer not handled. */ + if (available > ring_buffer_mask - position_masked) { + available = ring_buffer_mask - position_masked; + } + + FN(Prepare)(self, BROTLI_FALSE, available, + ringbuffer + (position & ring_buffer_mask)); + self->next_ix = position; + BROTLI_UNUSED(num_bytes); +} + +static BROTLI_INLINE void FN(PrepareDistanceCache)( + HashRolling* BROTLI_RESTRICT self, + int* BROTLI_RESTRICT distance_cache) { + BROTLI_UNUSED(self); + BROTLI_UNUSED(distance_cache); +} + +static BROTLI_INLINE void FN(FindLongestMatch)( + HashRolling* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask, + const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix, + const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const size_t max_distance, + HasherSearchResult* BROTLI_RESTRICT out) { + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + size_t pos; + + if ((cur_ix & (JUMP - 1)) != 0) return; + + /* Not enough lookahead */ + if (max_length < CHUNKLEN) return; + + for (pos = self->next_ix; pos <= cur_ix; pos += JUMP) { + uint32_t code = self->state & MASK; + + uint8_t rem = data[pos & ring_buffer_mask]; + uint8_t add = data[(pos + CHUNKLEN) & ring_buffer_mask]; + size_t found_ix = FN(kInvalidPos); + + self->state = FN(HashRollingFunction)( + self->state, add, rem, self->factor, self->factor_remove); + + if (code < NUMBUCKETS) { + found_ix = self->table[code]; + self->table[code] = (uint32_t)pos; + if (pos == cur_ix && found_ix != FN(kInvalidPos)) { + /* The cast to 32-bit makes backward distances up to 4GB work even + if cur_ix is above 4GB, despite using 32-bit values in the table. */ + size_t backward = (uint32_t)(cur_ix - found_ix); + if (backward <= max_backward) { + const size_t found_ix_masked = found_ix & ring_buffer_mask; + const size_t len = FindMatchLengthWithLimit(&data[found_ix_masked], + &data[cur_ix_masked], + max_length); + if (len >= 4 && len > out->len) { + score_t score = BackwardReferenceScore(len, backward); + if (score > out->score) { + out->len = len; + out->distance = backward; + out->score = score; + out->len_code_delta = 0; + } + } + } + } + } + } + + self->next_ix = cur_ix + JUMP; + + /* NOTE: this hasher does not search in the dictionary. It is used as + backup-hasher, the main hasher already searches in it. */ + BROTLI_UNUSED(dictionary); + BROTLI_UNUSED(distance_cache); + BROTLI_UNUSED(dictionary_distance); + BROTLI_UNUSED(max_distance); +} + +#undef HashRolling diff --git a/packages/runtime/vendor/brotli/c/enc/hash_to_binary_tree_inc.h b/packages/runtime/vendor/brotli/c/enc/hash_to_binary_tree_inc.h new file mode 100644 index 000000000..a639d2d4b --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/hash_to_binary_tree_inc.h @@ -0,0 +1,330 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN, BUCKET_BITS, MAX_TREE_COMP_LENGTH, + MAX_TREE_SEARCH_DEPTH */ + +/* A (forgetful) hash table where each hash bucket contains a binary tree of + sequences whose first 4 bytes share the same hash code. + Each sequence is MAX_TREE_COMP_LENGTH long and is identified by its starting + position in the input data. The binary tree is sorted by the lexicographic + order of the sequences, and it is also a max-heap with respect to the + starting positions. */ + +#define HashToBinaryTree HASHER() + +#define BUCKET_SIZE (1 << BUCKET_BITS) + +static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; } +static BROTLI_INLINE size_t FN(StoreLookahead)(void) { + return MAX_TREE_COMP_LENGTH; +} + +static uint32_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) { + uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32; + /* The higher bits contain more mixture from the multiplication, + so we take our results from there. */ + return h >> (32 - BUCKET_BITS); +} + +typedef struct HashToBinaryTree { + /* The window size minus 1 */ + size_t window_mask_; + + /* Hash table that maps the 4-byte hashes of the sequence to the last + position where this hash was found, which is the root of the binary + tree of sequences that share this hash bucket. */ + uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */ + + /* A position used to mark a non-existent sequence, i.e. a tree is empty if + its root is at invalid_pos_ and a node is a leaf if both its children + are at invalid_pos_. */ + uint32_t invalid_pos_; + + /* --- Dynamic size members --- */ + + /* The union of the binary trees of each hash bucket. The root of the tree + corresponding to a hash is a sequence starting at buckets_[hash] and + the left and right children of a sequence starting at pos are + forest_[2 * pos] and forest_[2 * pos + 1]. */ + uint32_t* forest_; /* uint32_t[2 * num_nodes] */ +} HashToBinaryTree; + +static void FN(Initialize)( + HasherCommon* common, HashToBinaryTree* BROTLI_RESTRICT self, + const BrotliEncoderParams* params) { + self->buckets_ = (uint32_t*)common->extra[0]; + self->forest_ = (uint32_t*)common->extra[1]; + + self->window_mask_ = (1u << params->lgwin) - 1u; + self->invalid_pos_ = (uint32_t)(0 - self->window_mask_); +} + +static void FN(Prepare) + (HashToBinaryTree* BROTLI_RESTRICT self, BROTLI_BOOL one_shot, + size_t input_size, const uint8_t* BROTLI_RESTRICT data) { + uint32_t invalid_pos = self->invalid_pos_; + uint32_t i; + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + BROTLI_UNUSED(data); + BROTLI_UNUSED(one_shot); + BROTLI_UNUSED(input_size); + for (i = 0; i < BUCKET_SIZE; i++) { + buckets[i] = invalid_pos; + } +} + +static BROTLI_INLINE void FN(HashMemAllocInBytes)( + const BrotliEncoderParams* params, BROTLI_BOOL one_shot, + size_t input_size, size_t* alloc_size) { + size_t num_nodes = (size_t)1 << params->lgwin; + if (one_shot && input_size < num_nodes) { + num_nodes = input_size; + } + alloc_size[0] = sizeof(uint32_t) * BUCKET_SIZE; + alloc_size[1] = 2 * sizeof(uint32_t) * num_nodes; +} + +static BROTLI_INLINE size_t FN(LeftChildIndex)( + HashToBinaryTree* BROTLI_RESTRICT self, + const size_t pos) { + return 2 * (pos & self->window_mask_); +} + +static BROTLI_INLINE size_t FN(RightChildIndex)( + HashToBinaryTree* BROTLI_RESTRICT self, + const size_t pos) { + return 2 * (pos & self->window_mask_) + 1; +} + +/* Stores the hash of the next 4 bytes and in a single tree-traversal, the + hash bucket's binary tree is searched for matches and is re-rooted at the + current position. + + If less than MAX_TREE_COMP_LENGTH data is available, the hash bucket of the + current position is searched for matches, but the state of the hash table + is not changed, since we can not know the final sorting order of the + current (incomplete) sequence. + + This function must be called with increasing cur_ix positions. */ +static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)( + HashToBinaryTree* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data, + const size_t cur_ix, const size_t ring_buffer_mask, const size_t max_length, + const size_t max_backward, size_t* const BROTLI_RESTRICT best_len, + BackwardMatch* BROTLI_RESTRICT matches) { + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + const size_t max_comp_len = + BROTLI_MIN(size_t, max_length, MAX_TREE_COMP_LENGTH); + const BROTLI_BOOL should_reroot_tree = + TO_BROTLI_BOOL(max_length >= MAX_TREE_COMP_LENGTH); + const uint32_t key = FN(HashBytes)(&data[cur_ix_masked]); + uint32_t* BROTLI_RESTRICT buckets = self->buckets_; + uint32_t* BROTLI_RESTRICT forest = self->forest_; + size_t prev_ix = buckets[key]; + /* The forest index of the rightmost node of the left subtree of the new + root, updated as we traverse and re-root the tree of the hash bucket. */ + size_t node_left = FN(LeftChildIndex)(self, cur_ix); + /* The forest index of the leftmost node of the right subtree of the new + root, updated as we traverse and re-root the tree of the hash bucket. */ + size_t node_right = FN(RightChildIndex)(self, cur_ix); + /* The match length of the rightmost node of the left subtree of the new + root, updated as we traverse and re-root the tree of the hash bucket. */ + size_t best_len_left = 0; + /* The match length of the leftmost node of the right subtree of the new + root, updated as we traverse and re-root the tree of the hash bucket. */ + size_t best_len_right = 0; + size_t depth_remaining; + if (should_reroot_tree) { + buckets[key] = (uint32_t)cur_ix; + } + for (depth_remaining = MAX_TREE_SEARCH_DEPTH; ; --depth_remaining) { + const size_t backward = cur_ix - prev_ix; + const size_t prev_ix_masked = prev_ix & ring_buffer_mask; + if (backward == 0 || backward > max_backward || depth_remaining == 0) { + if (should_reroot_tree) { + forest[node_left] = self->invalid_pos_; + forest[node_right] = self->invalid_pos_; + } + break; + } + { + const size_t cur_len = BROTLI_MIN(size_t, best_len_left, best_len_right); + size_t len; + BROTLI_DCHECK(cur_len <= MAX_TREE_COMP_LENGTH); + len = cur_len + + FindMatchLengthWithLimit(&data[cur_ix_masked + cur_len], + &data[prev_ix_masked + cur_len], + max_length - cur_len); + BROTLI_DCHECK( + 0 == memcmp(&data[cur_ix_masked], &data[prev_ix_masked], len)); + if (matches && len > *best_len) { + *best_len = len; + InitBackwardMatch(matches++, backward, len); + } + if (len >= max_comp_len) { + if (should_reroot_tree) { + forest[node_left] = forest[FN(LeftChildIndex)(self, prev_ix)]; + forest[node_right] = forest[FN(RightChildIndex)(self, prev_ix)]; + } + break; + } + if (data[cur_ix_masked + len] > data[prev_ix_masked + len]) { + best_len_left = len; + if (should_reroot_tree) { + forest[node_left] = (uint32_t)prev_ix; + } + node_left = FN(RightChildIndex)(self, prev_ix); + prev_ix = forest[node_left]; + } else { + best_len_right = len; + if (should_reroot_tree) { + forest[node_right] = (uint32_t)prev_ix; + } + node_right = FN(LeftChildIndex)(self, prev_ix); + prev_ix = forest[node_right]; + } + } + } + return matches; +} + +/* Finds all backward matches of &data[cur_ix & ring_buffer_mask] up to the + length of max_length and stores the position cur_ix in the hash table. + + Sets *num_matches to the number of matches found, and stores the found + matches in matches[0] to matches[*num_matches - 1]. The matches will be + sorted by strictly increasing length and (non-strictly) increasing + distance. */ +static BROTLI_INLINE size_t FN(FindAllMatches)( + HashToBinaryTree* BROTLI_RESTRICT self, + const BrotliEncoderDictionary* dictionary, + const uint8_t* BROTLI_RESTRICT data, + const size_t ring_buffer_mask, const size_t cur_ix, + const size_t max_length, const size_t max_backward, + const size_t dictionary_distance, const BrotliEncoderParams* params, + BackwardMatch* matches) { + BackwardMatch* const orig_matches = matches; + const size_t cur_ix_masked = cur_ix & ring_buffer_mask; + size_t best_len = 1; + const size_t short_match_max_backward = + params->quality != HQ_ZOPFLIFICATION_QUALITY ? 16 : 64; + size_t stop = cur_ix - short_match_max_backward; + uint32_t dict_matches[BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN + 1]; + size_t i; + if (cur_ix < short_match_max_backward) { stop = 0; } + for (i = cur_ix - 1; i > stop && best_len <= 2; --i) { + size_t prev_ix = i; + const size_t backward = cur_ix - prev_ix; + if (BROTLI_PREDICT_FALSE(backward > max_backward)) { + break; + } + prev_ix &= ring_buffer_mask; + if (data[cur_ix_masked] != data[prev_ix] || + data[cur_ix_masked + 1] != data[prev_ix + 1]) { + continue; + } + { + const size_t len = + FindMatchLengthWithLimit(&data[prev_ix], &data[cur_ix_masked], + max_length); + if (len > best_len) { + best_len = len; + InitBackwardMatch(matches++, backward, len); + } + } + } + if (best_len < max_length) { + matches = FN(StoreAndFindMatches)(self, data, cur_ix, + ring_buffer_mask, max_length, max_backward, &best_len, matches); + } + for (i = 0; i <= BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN; ++i) { + dict_matches[i] = kInvalidMatch; + } + { + size_t minlen = BROTLI_MAX(size_t, 4, best_len + 1); + if (BrotliFindAllStaticDictionaryMatches(dictionary, + &data[cur_ix_masked], minlen, max_length, &dict_matches[0])) { + size_t maxlen = BROTLI_MIN( + size_t, BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN, max_length); + size_t l; + for (l = minlen; l <= maxlen; ++l) { + uint32_t dict_id = dict_matches[l]; + if (dict_id < kInvalidMatch) { + size_t distance = dictionary_distance + (dict_id >> 5) + 1; + if (distance <= params->dist.max_distance) { + InitDictionaryBackwardMatch(matches++, distance, l, dict_id & 31); + } + } + } + } + } + return (size_t)(matches - orig_matches); +} + +/* Stores the hash of the next 4 bytes and re-roots the binary tree at the + current sequence, without returning any matches. + REQUIRES: ix + MAX_TREE_COMP_LENGTH <= end-of-current-block */ +static BROTLI_INLINE void FN(Store)(HashToBinaryTree* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, + const size_t mask, const size_t ix) { + /* Maximum distance is window size - 16, see section 9.1. of the spec. */ + const size_t max_backward = self->window_mask_ - BROTLI_WINDOW_GAP + 1; + FN(StoreAndFindMatches)(self, data, ix, mask, MAX_TREE_COMP_LENGTH, + max_backward, NULL, NULL); +} + +static BROTLI_INLINE void FN(StoreRange)(HashToBinaryTree* BROTLI_RESTRICT self, + const uint8_t* BROTLI_RESTRICT data, const size_t mask, + const size_t ix_start, const size_t ix_end) { + size_t i = ix_start; + size_t j = ix_start; + if (ix_start + 63 <= ix_end) { + i = ix_end - 63; + } + if (ix_start + 512 <= i) { + for (; j < i; j += 8) { + FN(Store)(self, data, mask, j); + } + } + for (; i < ix_end; ++i) { + FN(Store)(self, data, mask, i); + } +} + +static BROTLI_INLINE void FN(StitchToPreviousBlock)( + HashToBinaryTree* BROTLI_RESTRICT self, + size_t num_bytes, size_t position, const uint8_t* ringbuffer, + size_t ringbuffer_mask) { + if (num_bytes >= FN(HashTypeLength)() - 1 && + position >= MAX_TREE_COMP_LENGTH) { + /* Store the last `MAX_TREE_COMP_LENGTH - 1` positions in the hasher. + These could not be calculated before, since they require knowledge + of both the previous and the current block. */ + const size_t i_start = position - MAX_TREE_COMP_LENGTH + 1; + const size_t i_end = BROTLI_MIN(size_t, position, i_start + num_bytes); + size_t i; + for (i = i_start; i < i_end; ++i) { + /* Maximum distance is window size - 16, see section 9.1. of the spec. + Furthermore, we have to make sure that we don't look further back + from the start of the next block than the window size, otherwise we + could access already overwritten areas of the ring-buffer. */ + const size_t max_backward = + self->window_mask_ - BROTLI_MAX(size_t, + BROTLI_WINDOW_GAP - 1, + position - i); + /* We know that i + MAX_TREE_COMP_LENGTH <= position + num_bytes, i.e. the + end of the current block and that we have at least + MAX_TREE_COMP_LENGTH tail in the ring-buffer. */ + FN(StoreAndFindMatches)(self, ringbuffer, i, ringbuffer_mask, + MAX_TREE_COMP_LENGTH, max_backward, NULL, NULL); + } + } +} + +#undef BUCKET_SIZE + +#undef HashToBinaryTree diff --git a/packages/runtime/vendor/brotli/c/enc/histogram.c b/packages/runtime/vendor/brotli/c/enc/histogram.c new file mode 100644 index 000000000..43e4b38e3 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/histogram.c @@ -0,0 +1,101 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Build per-context histograms of literals, commands and distance codes. */ + +#include "histogram.h" + +#include "../common/context.h" +#include "../common/platform.h" +#include "block_splitter.h" +#include "command.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct BlockSplitIterator { + const BlockSplit* split_; /* Not owned. */ + size_t idx_; + size_t type_; + size_t length_; +} BlockSplitIterator; + +static void InitBlockSplitIterator(BlockSplitIterator* self, + const BlockSplit* split) { + self->split_ = split; + self->idx_ = 0; + self->type_ = 0; + self->length_ = split->lengths ? split->lengths[0] : 0; +} + +static void BlockSplitIteratorNext(BlockSplitIterator* self) { + if (self->length_ == 0) { + ++self->idx_; + self->type_ = self->split_->types[self->idx_]; + self->length_ = self->split_->lengths[self->idx_]; + } + --self->length_; +} + +void BrotliBuildHistogramsWithContext( + const Command* cmds, const size_t num_commands, + const BlockSplit* literal_split, const BlockSplit* insert_and_copy_split, + const BlockSplit* dist_split, const uint8_t* ringbuffer, size_t start_pos, + size_t mask, uint8_t prev_byte, uint8_t prev_byte2, + const ContextType* context_modes, HistogramLiteral* literal_histograms, + HistogramCommand* insert_and_copy_histograms, + HistogramDistance* copy_dist_histograms) { + size_t pos = start_pos; + BlockSplitIterator literal_it; + BlockSplitIterator insert_and_copy_it; + BlockSplitIterator dist_it; + size_t i; + + InitBlockSplitIterator(&literal_it, literal_split); + InitBlockSplitIterator(&insert_and_copy_it, insert_and_copy_split); + InitBlockSplitIterator(&dist_it, dist_split); + for (i = 0; i < num_commands; ++i) { + const Command* cmd = &cmds[i]; + size_t j; + BlockSplitIteratorNext(&insert_and_copy_it); + HistogramAddCommand(&insert_and_copy_histograms[insert_and_copy_it.type_], + cmd->cmd_prefix_); + /* TODO(eustas): unwrap iterator blocks. */ + for (j = cmd->insert_len_; j != 0; --j) { + size_t context; + BlockSplitIteratorNext(&literal_it); + context = literal_it.type_; + if (context_modes) { + ContextLut lut = BROTLI_CONTEXT_LUT(context_modes[context]); + context = (context << BROTLI_LITERAL_CONTEXT_BITS) + + BROTLI_CONTEXT(prev_byte, prev_byte2, lut); + } + HistogramAddLiteral(&literal_histograms[context], + ringbuffer[pos & mask]); + prev_byte2 = prev_byte; + prev_byte = ringbuffer[pos & mask]; + ++pos; + } + pos += CommandCopyLen(cmd); + if (CommandCopyLen(cmd)) { + prev_byte2 = ringbuffer[(pos - 2) & mask]; + prev_byte = ringbuffer[(pos - 1) & mask]; + if (cmd->cmd_prefix_ >= 128) { + size_t context; + BlockSplitIteratorNext(&dist_it); + context = (dist_it.type_ << BROTLI_DISTANCE_CONTEXT_BITS) + + CommandDistanceContext(cmd); + HistogramAddDistance(©_dist_histograms[context], + cmd->dist_prefix_ & 0x3FF); + } + } + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/histogram.h b/packages/runtime/vendor/brotli/c/enc/histogram.h new file mode 100644 index 000000000..a2accc331 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/histogram.h @@ -0,0 +1,60 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Models the histograms of literals, commands and distance codes. */ + +#ifndef BROTLI_ENC_HISTOGRAM_H_ +#define BROTLI_ENC_HISTOGRAM_H_ + +#include "../common/constants.h" +#include "../common/context.h" +#include "../common/platform.h" +#include "block_splitter.h" +#include "command.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* The distance symbols effectively used by "Large Window Brotli" (32-bit). */ +#define BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS 544 + +#define FN(X) X ## Literal +#define DATA_SIZE BROTLI_NUM_LITERAL_SYMBOLS +#define DataType uint8_t +#include "histogram_inc.h" /* NOLINT(build/include) */ +#undef DataType +#undef DATA_SIZE +#undef FN + +#define FN(X) X ## Command +#define DataType uint16_t +#define DATA_SIZE BROTLI_NUM_COMMAND_SYMBOLS +#include "histogram_inc.h" /* NOLINT(build/include) */ +#undef DATA_SIZE +#undef FN + +#define FN(X) X ## Distance +#define DATA_SIZE BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS +#include "histogram_inc.h" /* NOLINT(build/include) */ +#undef DataType +#undef DATA_SIZE +#undef FN + +BROTLI_INTERNAL void BrotliBuildHistogramsWithContext( + const Command* cmds, const size_t num_commands, + const BlockSplit* literal_split, const BlockSplit* insert_and_copy_split, + const BlockSplit* dist_split, const uint8_t* ringbuffer, size_t pos, + size_t mask, uint8_t prev_byte, uint8_t prev_byte2, + const ContextType* context_modes, HistogramLiteral* literal_histograms, + HistogramCommand* insert_and_copy_histograms, + HistogramDistance* copy_dist_histograms); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_HISTOGRAM_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/histogram_inc.h b/packages/runtime/vendor/brotli/c/enc/histogram_inc.h new file mode 100644 index 000000000..50eaf7468 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/histogram_inc.h @@ -0,0 +1,51 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: Histogram, DATA_SIZE, DataType */ + +/* A simple container for histograms of data in blocks. */ + +typedef struct FN(Histogram) { + uint32_t data_[DATA_SIZE]; + size_t total_count_; + double bit_cost_; +} FN(Histogram); + +static BROTLI_INLINE void FN(HistogramClear)(FN(Histogram)* self) { + memset(self->data_, 0, sizeof(self->data_)); + self->total_count_ = 0; + self->bit_cost_ = HUGE_VAL; +} + +static BROTLI_INLINE void FN(ClearHistograms)( + FN(Histogram)* array, size_t length) { + size_t i; + for (i = 0; i < length; ++i) FN(HistogramClear)(array + i); +} + +static BROTLI_INLINE void FN(HistogramAdd)(FN(Histogram)* self, size_t val) { + ++self->data_[val]; + ++self->total_count_; +} + +static BROTLI_INLINE void FN(HistogramAddVector)(FN(Histogram)* self, + const DataType* p, size_t n) { + self->total_count_ += n; + n += 1; + while (--n) ++self->data_[*p++]; +} + +static BROTLI_INLINE void FN(HistogramAddHistogram)(FN(Histogram)* self, + const FN(Histogram)* v) { + size_t i; + self->total_count_ += v->total_count_; + for (i = 0; i < DATA_SIZE; ++i) { + self->data_[i] += v->data_[i]; + } +} + +static BROTLI_INLINE size_t FN(HistogramDataSize)(void) { return DATA_SIZE; } diff --git a/packages/runtime/vendor/brotli/c/enc/literal_cost.c b/packages/runtime/vendor/brotli/c/enc/literal_cost.c new file mode 100644 index 000000000..c4e207d09 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/literal_cost.c @@ -0,0 +1,178 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Literal cost model to allow backward reference replacement to be efficient. +*/ + +#include "literal_cost.h" + +#include "../common/platform.h" +#include "fast_log.h" +#include "utf8_util.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static size_t UTF8Position(size_t last, size_t c, size_t clamp) { + if (c < 128) { + return 0; /* Next one is the 'Byte 1' again. */ + } else if (c >= 192) { /* Next one is the 'Byte 2' of utf-8 encoding. */ + return BROTLI_MIN(size_t, 1, clamp); + } else { + /* Let's decide over the last byte if this ends the sequence. */ + if (last < 0xE0) { + return 0; /* Completed two or three byte coding. */ + } else { /* Next one is the 'Byte 3' of utf-8 encoding. */ + return BROTLI_MIN(size_t, 2, clamp); + } + } +} + +static size_t DecideMultiByteStatsLevel(size_t pos, size_t len, size_t mask, + const uint8_t* data) { + size_t counts[3] = { 0 }; + size_t max_utf8 = 1; /* should be 2, but 1 compresses better. */ + size_t last_c = 0; + size_t i; + for (i = 0; i < len; ++i) { + size_t c = data[(pos + i) & mask]; + ++counts[UTF8Position(last_c, c, 2)]; + last_c = c; + } + if (counts[2] < 500) { + max_utf8 = 1; + } + if (counts[1] + counts[2] < 25) { + max_utf8 = 0; + } + return max_utf8; +} + +static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask, + const uint8_t* data, + size_t* histogram, float* cost) { + /* max_utf8 is 0 (normal ASCII single byte modeling), + 1 (for 2-byte UTF-8 modeling), or 2 (for 3-byte UTF-8 modeling). */ + const size_t max_utf8 = DecideMultiByteStatsLevel(pos, len, mask, data); + size_t window_half = 495; + size_t in_window = BROTLI_MIN(size_t, window_half, len); + size_t in_window_utf8[3] = { 0 }; + size_t i; + memset(histogram, 0, 3 * 256 * sizeof(histogram[0])); + + { /* Bootstrap histograms. */ + size_t last_c = 0; + size_t utf8_pos = 0; + for (i = 0; i < in_window; ++i) { + size_t c = data[(pos + i) & mask]; + ++histogram[256 * utf8_pos + c]; + ++in_window_utf8[utf8_pos]; + utf8_pos = UTF8Position(last_c, c, max_utf8); + last_c = c; + } + } + + /* Compute bit costs with sliding window. */ + for (i = 0; i < len; ++i) { + if (i >= window_half) { + /* Remove a byte in the past. */ + size_t c = + i < window_half + 1 ? 0 : data[(pos + i - window_half - 1) & mask]; + size_t last_c = + i < window_half + 2 ? 0 : data[(pos + i - window_half - 2) & mask]; + size_t utf8_pos2 = UTF8Position(last_c, c, max_utf8); + --histogram[256 * utf8_pos2 + data[(pos + i - window_half) & mask]]; + --in_window_utf8[utf8_pos2]; + } + if (i + window_half < len) { + /* Add a byte in the future. */ + size_t c = data[(pos + i + window_half - 1) & mask]; + size_t last_c = data[(pos + i + window_half - 2) & mask]; + size_t utf8_pos2 = UTF8Position(last_c, c, max_utf8); + ++histogram[256 * utf8_pos2 + data[(pos + i + window_half) & mask]]; + ++in_window_utf8[utf8_pos2]; + } + { + size_t c = i < 1 ? 0 : data[(pos + i - 1) & mask]; + size_t last_c = i < 2 ? 0 : data[(pos + i - 2) & mask]; + size_t utf8_pos = UTF8Position(last_c, c, max_utf8); + size_t masked_pos = (pos + i) & mask; + size_t histo = histogram[256 * utf8_pos + data[masked_pos]]; + static const size_t prologue_length = 2000; + static const double multiplier = 0.35 / 2000; + double lit_cost; + if (histo == 0) { + histo = 1; + } + lit_cost = FastLog2(in_window_utf8[utf8_pos]) - FastLog2(histo); + lit_cost += 0.02905; + if (lit_cost < 1.0) { + lit_cost *= 0.5; + lit_cost += 0.5; + } + /* Make the first bytes more expensive -- seems to help, not sure why. + Perhaps because the entropy source is changing its properties + rapidly in the beginning of the file, perhaps because the beginning + of the data is a statistical "anomaly". */ + if (i < prologue_length) { + lit_cost += 0.35 + multiplier * (double)i; + } + cost[i] = (float)lit_cost; + } + } +} + +void BrotliEstimateBitCostsForLiterals(size_t pos, size_t len, size_t mask, + const uint8_t* data, + size_t* histogram, float* cost) { + if (BrotliIsMostlyUTF8(data, pos, mask, len, kMinUTF8Ratio)) { + EstimateBitCostsForLiteralsUTF8(pos, len, mask, data, histogram, cost); + return; + } else { + size_t window_half = 2000; + size_t in_window = BROTLI_MIN(size_t, window_half, len); + size_t i; + memset(histogram, 0, 256 * sizeof(histogram[0])); + + /* Bootstrap histogram. */ + for (i = 0; i < in_window; ++i) { + ++histogram[data[(pos + i) & mask]]; + } + + /* Compute bit costs with sliding window. */ + for (i = 0; i < len; ++i) { + size_t histo; + if (i >= window_half) { + /* Remove a byte in the past. */ + --histogram[data[(pos + i - window_half) & mask]]; + --in_window; + } + if (i + window_half < len) { + /* Add a byte in the future. */ + ++histogram[data[(pos + i + window_half) & mask]]; + ++in_window; + } + histo = histogram[data[(pos + i) & mask]]; + if (histo == 0) { + histo = 1; + } + { + double lit_cost = FastLog2(in_window) - FastLog2(histo); + lit_cost += 0.029; + if (lit_cost < 1.0) { + lit_cost *= 0.5; + lit_cost += 0.5; + } + cost[i] = (float)lit_cost; + } + } + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/literal_cost.h b/packages/runtime/vendor/brotli/c/enc/literal_cost.h new file mode 100644 index 000000000..eb3f33836 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/literal_cost.h @@ -0,0 +1,30 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Literal cost model to allow backward reference replacement to be efficient. +*/ + +#ifndef BROTLI_ENC_LITERAL_COST_H_ +#define BROTLI_ENC_LITERAL_COST_H_ + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Estimates how many bits the literals in the interval [pos, pos + len) in the + ring-buffer (data, mask) will take entropy coded and writes these estimates + to the cost[0..len) array. */ +BROTLI_INTERNAL void BrotliEstimateBitCostsForLiterals( + size_t pos, size_t len, size_t mask, const uint8_t* data, size_t* histogram, + float* cost); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_LITERAL_COST_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/matching_tag_mask.h b/packages/runtime/vendor/brotli/c/enc/matching_tag_mask.h new file mode 100644 index 000000000..8a1be1d71 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/matching_tag_mask.h @@ -0,0 +1,69 @@ +#ifndef THIRD_PARTY_BROTLI_ENC_MATCHING_TAG_MASK_H_ +#define THIRD_PARTY_BROTLI_ENC_MATCHING_TAG_MASK_H_ + +#include "../common/platform.h" + +#if defined(__SSE2__) || defined(_M_AMD64) || \ + (defined(_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) +#define SUPPORTS_SSE_2 +#endif + +#if defined(SUPPORTS_SSE_2) +#include +#endif + + +static BROTLI_INLINE uint64_t GetMatchingTagMask( + size_t chunk_count, const uint8_t tag, + const uint8_t* BROTLI_RESTRICT tag_bucket, const size_t head) { + uint64_t matches = 0; +#if defined(SUPPORTS_SSE_2) + const __m128i comparison_mask = _mm_set1_epi8((char)tag); + size_t i; + for (i = 0; i < chunk_count && i < 4; i++) { + const __m128i chunk = + _mm_loadu_si128((const __m128i*)(const void*)(tag_bucket + 16 * i)); + const __m128i equal_mask = _mm_cmpeq_epi8(chunk, comparison_mask); + matches |= (uint64_t)_mm_movemask_epi8(equal_mask) << 16 * i; + } +#else + const int chunk_size = sizeof(size_t); + const size_t shift_amount = ((chunk_size * 8) - chunk_size); + const size_t xFF = ~((size_t)0); + const size_t x01 = xFF / 0xFF; + const size_t x80 = x01 << 7; + const size_t splat_char = tag * x01; + int i = ((int)chunk_count * 16) - chunk_size; + BROTLI_DCHECK((sizeof(size_t) == 4) || (sizeof(size_t) == 8)); +#if BROTLI_LITTLE_ENDIAN + const size_t extractMagic = (xFF / 0x7F) >> chunk_size; + do { + size_t chunk = BrotliUnalignedReadSizeT(&tag_bucket[i]); + chunk ^= splat_char; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunk_size; + matches |= (chunk * extractMagic) >> shift_amount; + i -= chunk_size; + } while (i >= 0); +#else + const size_t msb = xFF ^ (xFF >> 1); + const size_t extractMagic = (msb / 0x1FF) | msb; + do { + size_t chunk = BrotliUnalignedReadSizeT(&tag_bucket[i]); + chunk ^= splat_char; + chunk = (((chunk | x80) - x01) | chunk) & x80; + matches <<= chunk_size; + matches |= ((chunk >> 7) * extractMagic) >> shift_amount; + i -= chunk_size; + } while (i >= 0); +#endif + matches = ~matches; +#endif + if (chunk_count == 1) return BrotliRotateRight16((uint16_t)matches, head); + if (chunk_count == 2) return BrotliRotateRight32((uint32_t)matches, head); + return BrotliRotateRight64(matches, head); +} + +#undef SUPPORTS_SSE_2 + +#endif // THIRD_PARTY_BROTLI_ENC_MATCHING_TAG_MASK_H_ diff --git a/packages/runtime/vendor/brotli/c/enc/memory.c b/packages/runtime/vendor/brotli/c/enc/memory.c new file mode 100644 index 000000000..67f81ffde --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/memory.c @@ -0,0 +1,189 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Algorithms for distributing the literals and commands of a metablock between + block types and contexts. */ + +#include "memory.h" + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define MAX_NEW_ALLOCATED (BROTLI_ENCODER_MEMORY_MANAGER_SLOTS >> 2) +#define MAX_NEW_FREED (BROTLI_ENCODER_MEMORY_MANAGER_SLOTS >> 2) +#define MAX_PERM_ALLOCATED (BROTLI_ENCODER_MEMORY_MANAGER_SLOTS >> 1) + +#define PERM_ALLOCATED_OFFSET 0 +#define NEW_ALLOCATED_OFFSET MAX_PERM_ALLOCATED +#define NEW_FREED_OFFSET (MAX_PERM_ALLOCATED + MAX_NEW_ALLOCATED) + +void BrotliInitMemoryManager( + MemoryManager* m, brotli_alloc_func alloc_func, brotli_free_func free_func, + void* opaque) { + if (!alloc_func) { + m->alloc_func = BrotliDefaultAllocFunc; + m->free_func = BrotliDefaultFreeFunc; + m->opaque = 0; + } else { + m->alloc_func = alloc_func; + m->free_func = free_func; + m->opaque = opaque; + } +#if !defined(BROTLI_ENCODER_EXIT_ON_OOM) + m->is_oom = BROTLI_FALSE; + m->perm_allocated = 0; + m->new_allocated = 0; + m->new_freed = 0; +#endif /* BROTLI_ENCODER_EXIT_ON_OOM */ +} + +#if defined(BROTLI_ENCODER_EXIT_ON_OOM) + +void* BrotliAllocate(MemoryManager* m, size_t n) { + void* result = m->alloc_func(m->opaque, n); + if (!result) exit(EXIT_FAILURE); + return result; +} + +void BrotliFree(MemoryManager* m, void* p) { + m->free_func(m->opaque, p); +} + +void BrotliWipeOutMemoryManager(MemoryManager* m) { + BROTLI_UNUSED(m); +} + +#else /* BROTLI_ENCODER_EXIT_ON_OOM */ + +static void SortPointers(void** items, const size_t n) { + /* Shell sort. */ + /* TODO(eustas): fine-tune for "many slots" case */ + static const size_t gaps[] = {23, 10, 4, 1}; + int g = 0; + for (; g < 4; ++g) { + size_t gap = gaps[g]; + size_t i; + for (i = gap; i < n; ++i) { + size_t j = i; + void* tmp = items[i]; + for (; j >= gap && tmp < items[j - gap]; j -= gap) { + items[j] = items[j - gap]; + } + items[j] = tmp; + } + } +} + +static size_t Annihilate(void** a, size_t a_len, void** b, size_t b_len) { + size_t a_read_index = 0; + size_t b_read_index = 0; + size_t a_write_index = 0; + size_t b_write_index = 0; + size_t annihilated = 0; + while (a_read_index < a_len && b_read_index < b_len) { + if (a[a_read_index] == b[b_read_index]) { + a_read_index++; + b_read_index++; + annihilated++; + } else if (a[a_read_index] < b[b_read_index]) { + a[a_write_index++] = a[a_read_index++]; + } else { + b[b_write_index++] = b[b_read_index++]; + } + } + while (a_read_index < a_len) a[a_write_index++] = a[a_read_index++]; + while (b_read_index < b_len) b[b_write_index++] = b[b_read_index++]; + return annihilated; +} + +static void CollectGarbagePointers(MemoryManager* m) { + size_t annihilated; + SortPointers(m->pointers + NEW_ALLOCATED_OFFSET, m->new_allocated); + SortPointers(m->pointers + NEW_FREED_OFFSET, m->new_freed); + annihilated = Annihilate( + m->pointers + NEW_ALLOCATED_OFFSET, m->new_allocated, + m->pointers + NEW_FREED_OFFSET, m->new_freed); + m->new_allocated -= annihilated; + m->new_freed -= annihilated; + + if (m->new_freed != 0) { + annihilated = Annihilate( + m->pointers + PERM_ALLOCATED_OFFSET, m->perm_allocated, + m->pointers + NEW_FREED_OFFSET, m->new_freed); + m->perm_allocated -= annihilated; + m->new_freed -= annihilated; + BROTLI_DCHECK(m->new_freed == 0); + } + + if (m->new_allocated != 0) { + BROTLI_DCHECK(m->perm_allocated + m->new_allocated <= MAX_PERM_ALLOCATED); + memcpy(m->pointers + PERM_ALLOCATED_OFFSET + m->perm_allocated, + m->pointers + NEW_ALLOCATED_OFFSET, + sizeof(void*) * m->new_allocated); + m->perm_allocated += m->new_allocated; + m->new_allocated = 0; + SortPointers(m->pointers + PERM_ALLOCATED_OFFSET, m->perm_allocated); + } +} + +void* BrotliAllocate(MemoryManager* m, size_t n) { + void* result = m->alloc_func(m->opaque, n); + if (!result) { + m->is_oom = BROTLI_TRUE; + return NULL; + } + if (m->new_allocated == MAX_NEW_ALLOCATED) CollectGarbagePointers(m); + m->pointers[NEW_ALLOCATED_OFFSET + (m->new_allocated++)] = result; + return result; +} + +void BrotliFree(MemoryManager* m, void* p) { + if (!p) return; + m->free_func(m->opaque, p); + if (m->new_freed == MAX_NEW_FREED) CollectGarbagePointers(m); + m->pointers[NEW_FREED_OFFSET + (m->new_freed++)] = p; +} + +void BrotliWipeOutMemoryManager(MemoryManager* m) { + size_t i; + CollectGarbagePointers(m); + /* Now all unfreed pointers are in perm-allocated list. */ + for (i = 0; i < m->perm_allocated; ++i) { + m->free_func(m->opaque, m->pointers[PERM_ALLOCATED_OFFSET + i]); + } + m->perm_allocated = 0; +} + +#endif /* BROTLI_ENCODER_EXIT_ON_OOM */ + +void* BrotliBootstrapAlloc(size_t size, + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) { + if (!alloc_func && !free_func) { + return malloc(size); + } else if (alloc_func && free_func) { + return alloc_func(opaque, size); + } + return NULL; +} + +void BrotliBootstrapFree(void* address, MemoryManager* m) { + if (!address) { + /* Should not happen! */ + return; + } else { + /* Copy values, as those would be freed. */ + brotli_free_func free_func = m->free_func; + void* opaque = m->opaque; + free_func(opaque, address); + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/memory.h b/packages/runtime/vendor/brotli/c/enc/memory.h new file mode 100644 index 000000000..d8374815b --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/memory.h @@ -0,0 +1,127 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Macros for memory management. */ + +#ifndef BROTLI_ENC_MEMORY_H_ +#define BROTLI_ENC_MEMORY_H_ + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if !defined(BROTLI_ENCODER_CLEANUP_ON_OOM) && \ + !defined(BROTLI_ENCODER_EXIT_ON_OOM) +#define BROTLI_ENCODER_EXIT_ON_OOM +#endif + +#if !defined(BROTLI_ENCODER_EXIT_ON_OOM) +#if defined(BROTLI_EXPERIMENTAL) +#define BROTLI_ENCODER_MEMORY_MANAGER_SLOTS (48*1024) +#else /* BROTLI_EXPERIMENTAL */ +#define BROTLI_ENCODER_MEMORY_MANAGER_SLOTS 256 +#endif /* BROTLI_EXPERIMENTAL */ +#else /* BROTLI_ENCODER_EXIT_ON_OOM */ +#define BROTLI_ENCODER_MEMORY_MANAGER_SLOTS 0 +#endif /* BROTLI_ENCODER_EXIT_ON_OOM */ + +typedef struct MemoryManager { + brotli_alloc_func alloc_func; + brotli_free_func free_func; + void* opaque; +#if !defined(BROTLI_ENCODER_EXIT_ON_OOM) + BROTLI_BOOL is_oom; + size_t perm_allocated; + size_t new_allocated; + size_t new_freed; + void* pointers[BROTLI_ENCODER_MEMORY_MANAGER_SLOTS]; +#endif /* BROTLI_ENCODER_EXIT_ON_OOM */ +} MemoryManager; + +BROTLI_INTERNAL void BrotliInitMemoryManager( + MemoryManager* m, brotli_alloc_func alloc_func, brotli_free_func free_func, + void* opaque); + +BROTLI_INTERNAL void* BrotliAllocate(MemoryManager* m, size_t n); +#define BROTLI_ALLOC(M, T, N) \ + ((N) > 0 ? ((T*)BrotliAllocate((M), (N) * sizeof(T))) : NULL) + +BROTLI_INTERNAL void BrotliFree(MemoryManager* m, void* p); +#define BROTLI_FREE(M, P) { \ + BrotliFree((M), (P)); \ + P = NULL; \ +} + +#if defined(BROTLI_ENCODER_EXIT_ON_OOM) +#define BROTLI_IS_OOM(M) (!!0) +#else /* BROTLI_ENCODER_EXIT_ON_OOM */ +#define BROTLI_IS_OOM(M) (!!(M)->is_oom) +#endif /* BROTLI_ENCODER_EXIT_ON_OOM */ + +/* +BROTLI_IS_NULL is a fake check, BROTLI_IS_OOM does the heavy lifting. +The only purpose of it is to explain static analyzers the state of things. +NB: use ONLY together with BROTLI_IS_OOM + AND ONLY for allocations in the current scope. + */ +#if defined(__clang_analyzer__) && !defined(BROTLI_ENCODER_EXIT_ON_OOM) +#define BROTLI_IS_NULL(A) ((A) == nullptr) +#else /* defined(__clang_analyzer__) */ +#define BROTLI_IS_NULL(A) (!!0) +#endif /* defined(__clang_analyzer__) */ + +BROTLI_INTERNAL void BrotliWipeOutMemoryManager(MemoryManager* m); + +/* +Dynamically grows array capacity to at least the requested size +M: MemoryManager +T: data type +A: array +C: capacity +R: requested size +*/ +#define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) { \ + if (C < (R)) { \ + size_t _new_size = (C == 0) ? (R) : C; \ + T* new_array; \ + while (_new_size < (R)) _new_size *= 2; \ + new_array = BROTLI_ALLOC((M), T, _new_size); \ + if (!BROTLI_IS_OOM(M) && !BROTLI_IS_NULL(new_array) && C != 0) \ + memcpy(new_array, A, C * sizeof(T)); \ + BROTLI_FREE((M), A); \ + A = new_array; \ + C = _new_size; \ + } \ +} + +/* +Appends value and dynamically grows array capacity when needed +M: MemoryManager +T: data type +A: array +C: array capacity +S: array size +V: value to append +*/ +#define BROTLI_ENSURE_CAPACITY_APPEND(M, T, A, C, S, V) { \ + (S)++; \ + BROTLI_ENSURE_CAPACITY(M, T, A, C, S); \ + A[(S) - 1] = (V); \ +} + +/* "Bootstrap" allocations are not tracked by memory manager; should be used + only to allocate MemoryManager itself (or structure containing it). */ +BROTLI_INTERNAL void* BrotliBootstrapAlloc(size_t size, + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); +BROTLI_INTERNAL void BrotliBootstrapFree(void* address, MemoryManager* m); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_MEMORY_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/metablock.c b/packages/runtime/vendor/brotli/c/enc/metablock.c new file mode 100644 index 000000000..dfe8120c8 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/metablock.c @@ -0,0 +1,675 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Algorithms for distributing the literals and commands of a metablock between + block types and contexts. */ + +#include "metablock.h" + +#include "../common/constants.h" +#include "../common/context.h" +#include "../common/platform.h" +#include "bit_cost.h" +#include "block_splitter.h" +#include "cluster.h" +#include "command.h" +#include "entropy_encode.h" +#include "histogram.h" +#include "memory.h" +#include "params.h" +#include "prefix.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +void BrotliInitDistanceParams(BrotliDistanceParams* dist_params, + uint32_t npostfix, uint32_t ndirect, BROTLI_BOOL large_window) { + uint32_t alphabet_size_max; + uint32_t alphabet_size_limit; + uint32_t max_distance; + + dist_params->distance_postfix_bits = npostfix; + dist_params->num_direct_distance_codes = ndirect; + + alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE( + npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS); + alphabet_size_limit = alphabet_size_max; + max_distance = ndirect + (1U << (BROTLI_MAX_DISTANCE_BITS + npostfix + 2)) - + (1U << (npostfix + 2)); + + if (large_window) { + BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit( + BROTLI_MAX_ALLOWED_DISTANCE, npostfix, ndirect); + alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE( + npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS); + alphabet_size_limit = limit.max_alphabet_size; + max_distance = limit.max_distance; + } + + dist_params->alphabet_size_max = alphabet_size_max; + dist_params->alphabet_size_limit = alphabet_size_limit; + dist_params->max_distance = max_distance; +} + +static void RecomputeDistancePrefixes(Command* cmds, + size_t num_commands, + const BrotliDistanceParams* orig_params, + const BrotliDistanceParams* new_params) { + size_t i; + + if (orig_params->distance_postfix_bits == new_params->distance_postfix_bits && + orig_params->num_direct_distance_codes == + new_params->num_direct_distance_codes) { + return; + } + + for (i = 0; i < num_commands; ++i) { + Command* cmd = &cmds[i]; + if (CommandCopyLen(cmd) && cmd->cmd_prefix_ >= 128) { + PrefixEncodeCopyDistance(CommandRestoreDistanceCode(cmd, orig_params), + new_params->num_direct_distance_codes, + new_params->distance_postfix_bits, + &cmd->dist_prefix_, + &cmd->dist_extra_); + } + } +} + +static BROTLI_BOOL ComputeDistanceCost(const Command* cmds, + size_t num_commands, + const BrotliDistanceParams* orig_params, + const BrotliDistanceParams* new_params, + double* cost, + HistogramDistance* tmp) { + size_t i; + BROTLI_BOOL equal_params = BROTLI_FALSE; + uint16_t dist_prefix; + uint32_t dist_extra; + double extra_bits = 0.0; + HistogramClearDistance(tmp); + + if (orig_params->distance_postfix_bits == new_params->distance_postfix_bits && + orig_params->num_direct_distance_codes == + new_params->num_direct_distance_codes) { + equal_params = BROTLI_TRUE; + } + + for (i = 0; i < num_commands; i++) { + const Command* cmd = &cmds[i]; + if (CommandCopyLen(cmd) && cmd->cmd_prefix_ >= 128) { + if (equal_params) { + dist_prefix = cmd->dist_prefix_; + } else { + uint32_t distance = CommandRestoreDistanceCode(cmd, orig_params); + if (distance > new_params->max_distance) { + return BROTLI_FALSE; + } + PrefixEncodeCopyDistance(distance, + new_params->num_direct_distance_codes, + new_params->distance_postfix_bits, + &dist_prefix, + &dist_extra); + } + HistogramAddDistance(tmp, dist_prefix & 0x3FF); + extra_bits += dist_prefix >> 10; + } + } + + *cost = BrotliPopulationCostDistance(tmp) + extra_bits; + return BROTLI_TRUE; +} + +void BrotliBuildMetaBlock(MemoryManager* m, + const uint8_t* ringbuffer, + const size_t pos, + const size_t mask, + BrotliEncoderParams* params, + uint8_t prev_byte, + uint8_t prev_byte2, + Command* cmds, + size_t num_commands, + ContextType literal_context_mode, + MetaBlockSplit* mb) { + /* Histogram ids need to fit in one byte. */ + static const size_t kMaxNumberOfHistograms = 256; + HistogramDistance* distance_histograms; + HistogramLiteral* literal_histograms; + ContextType* literal_context_modes = NULL; + size_t literal_histograms_size; + size_t distance_histograms_size; + size_t i; + size_t literal_context_multiplier = 1; + uint32_t npostfix; + uint32_t ndirect_msb = 0; + BROTLI_BOOL check_orig = BROTLI_TRUE; + double best_dist_cost = 1e99; + BrotliDistanceParams orig_params = params->dist; + BrotliDistanceParams new_params = params->dist; + HistogramDistance* tmp = BROTLI_ALLOC(m, HistogramDistance, 1); + + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(tmp)) return; + + for (npostfix = 0; npostfix <= BROTLI_MAX_NPOSTFIX; npostfix++) { + for (; ndirect_msb < 16; ndirect_msb++) { + uint32_t ndirect = ndirect_msb << npostfix; + BROTLI_BOOL skip; + double dist_cost; + BrotliInitDistanceParams(&new_params, npostfix, ndirect, + params->large_window); + if (npostfix == orig_params.distance_postfix_bits && + ndirect == orig_params.num_direct_distance_codes) { + check_orig = BROTLI_FALSE; + } + skip = !ComputeDistanceCost( + cmds, num_commands, &orig_params, &new_params, &dist_cost, tmp); + if (skip || (dist_cost > best_dist_cost)) { + break; + } + best_dist_cost = dist_cost; + params->dist = new_params; + } + if (ndirect_msb > 0) ndirect_msb--; + ndirect_msb /= 2; + } + if (check_orig) { + double dist_cost; + ComputeDistanceCost(cmds, num_commands, &orig_params, &orig_params, + &dist_cost, tmp); + if (dist_cost < best_dist_cost) { + /* NB: currently unused; uncomment when more param tuning is added. */ + /* best_dist_cost = dist_cost; */ + params->dist = orig_params; + } + } + BROTLI_FREE(m, tmp); + RecomputeDistancePrefixes(cmds, num_commands, &orig_params, ¶ms->dist); + + BrotliSplitBlock(m, cmds, num_commands, + ringbuffer, pos, mask, params, + &mb->literal_split, + &mb->command_split, + &mb->distance_split); + if (BROTLI_IS_OOM(m)) return; + + if (!params->disable_literal_context_modeling) { + literal_context_multiplier = 1 << BROTLI_LITERAL_CONTEXT_BITS; + literal_context_modes = + BROTLI_ALLOC(m, ContextType, mb->literal_split.num_types); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literal_context_modes)) return; + for (i = 0; i < mb->literal_split.num_types; ++i) { + literal_context_modes[i] = literal_context_mode; + } + } + + literal_histograms_size = + mb->literal_split.num_types * literal_context_multiplier; + literal_histograms = + BROTLI_ALLOC(m, HistogramLiteral, literal_histograms_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(literal_histograms)) return; + ClearHistogramsLiteral(literal_histograms, literal_histograms_size); + + distance_histograms_size = + mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS; + distance_histograms = + BROTLI_ALLOC(m, HistogramDistance, distance_histograms_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(distance_histograms)) return; + ClearHistogramsDistance(distance_histograms, distance_histograms_size); + + BROTLI_DCHECK(mb->command_histograms == 0); + mb->command_histograms_size = mb->command_split.num_types; + mb->command_histograms = + BROTLI_ALLOC(m, HistogramCommand, mb->command_histograms_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->command_histograms)) return; + ClearHistogramsCommand(mb->command_histograms, mb->command_histograms_size); + + BrotliBuildHistogramsWithContext(cmds, num_commands, + &mb->literal_split, &mb->command_split, &mb->distance_split, + ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_modes, + literal_histograms, mb->command_histograms, distance_histograms); + BROTLI_FREE(m, literal_context_modes); + + BROTLI_DCHECK(mb->literal_context_map == 0); + mb->literal_context_map_size = + mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS; + mb->literal_context_map = + BROTLI_ALLOC(m, uint32_t, mb->literal_context_map_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_context_map)) return; + + BROTLI_DCHECK(mb->literal_histograms == 0); + mb->literal_histograms_size = mb->literal_context_map_size; + mb->literal_histograms = + BROTLI_ALLOC(m, HistogramLiteral, mb->literal_histograms_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_histograms)) return; + + BrotliClusterHistogramsLiteral(m, literal_histograms, literal_histograms_size, + kMaxNumberOfHistograms, mb->literal_histograms, + &mb->literal_histograms_size, mb->literal_context_map); + if (BROTLI_IS_OOM(m)) return; + BROTLI_FREE(m, literal_histograms); + + if (params->disable_literal_context_modeling) { + /* Distribute assignment to all contexts. */ + for (i = mb->literal_split.num_types; i != 0;) { + size_t j = 0; + i--; + for (; j < (1 << BROTLI_LITERAL_CONTEXT_BITS); j++) { + mb->literal_context_map[(i << BROTLI_LITERAL_CONTEXT_BITS) + j] = + mb->literal_context_map[i]; + } + } + } + + BROTLI_DCHECK(mb->distance_context_map == 0); + mb->distance_context_map_size = + mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS; + mb->distance_context_map = + BROTLI_ALLOC(m, uint32_t, mb->distance_context_map_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->distance_context_map)) return; + + BROTLI_DCHECK(mb->distance_histograms == 0); + mb->distance_histograms_size = mb->distance_context_map_size; + mb->distance_histograms = + BROTLI_ALLOC(m, HistogramDistance, mb->distance_histograms_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->distance_histograms)) return; + + BrotliClusterHistogramsDistance(m, distance_histograms, + mb->distance_context_map_size, + kMaxNumberOfHistograms, + mb->distance_histograms, + &mb->distance_histograms_size, + mb->distance_context_map); + if (BROTLI_IS_OOM(m)) return; + BROTLI_FREE(m, distance_histograms); +} + +#define FN(X) X ## Literal +#include "metablock_inc.h" /* NOLINT(build/include) */ +#undef FN + +#define FN(X) X ## Command +#include "metablock_inc.h" /* NOLINT(build/include) */ +#undef FN + +#define FN(X) X ## Distance +#include "metablock_inc.h" /* NOLINT(build/include) */ +#undef FN + +/* Greedy block splitter for one block category (literal, command or distance). + Gathers histograms for all context buckets. */ +typedef struct ContextBlockSplitter { + /* Alphabet size of particular block category. */ + size_t alphabet_size_; + size_t num_contexts_; + size_t max_block_types_; + /* We collect at least this many symbols for each block. */ + size_t min_block_size_; + /* We merge histograms A and B if + entropy(A+B) < entropy(A) + entropy(B) + split_threshold_, + where A is the current histogram and B is the histogram of the last or the + second last block type. */ + double split_threshold_; + + size_t num_blocks_; + BlockSplit* split_; /* not owned */ + HistogramLiteral* histograms_; /* not owned */ + size_t* histograms_size_; /* not owned */ + + /* The number of symbols that we want to collect before deciding on whether + or not to merge the block with a previous one or emit a new block. */ + size_t target_block_size_; + /* The number of symbols in the current histogram. */ + size_t block_size_; + /* Offset of the current histogram. */ + size_t curr_histogram_ix_; + /* Offset of the histograms of the previous two block types. */ + size_t last_histogram_ix_[2]; + /* Entropy of the previous two block types. */ + double last_entropy_[2 * BROTLI_MAX_STATIC_CONTEXTS]; + /* The number of times we merged the current block with the last one. */ + size_t merge_last_count_; +} ContextBlockSplitter; + +static void InitContextBlockSplitter( + MemoryManager* m, ContextBlockSplitter* self, size_t alphabet_size, + size_t num_contexts, size_t min_block_size, double split_threshold, + size_t num_symbols, BlockSplit* split, HistogramLiteral** histograms, + size_t* histograms_size) { + size_t max_num_blocks = num_symbols / min_block_size + 1; + size_t max_num_types; + BROTLI_DCHECK(num_contexts <= BROTLI_MAX_STATIC_CONTEXTS); + + self->alphabet_size_ = alphabet_size; + self->num_contexts_ = num_contexts; + self->max_block_types_ = BROTLI_MAX_NUMBER_OF_BLOCK_TYPES / num_contexts; + self->min_block_size_ = min_block_size; + self->split_threshold_ = split_threshold; + self->num_blocks_ = 0; + self->split_ = split; + self->histograms_size_ = histograms_size; + self->target_block_size_ = min_block_size; + self->block_size_ = 0; + self->curr_histogram_ix_ = 0; + self->merge_last_count_ = 0; + + /* We have to allocate one more histogram than the maximum number of block + types for the current histogram when the meta-block is too big. */ + max_num_types = + BROTLI_MIN(size_t, max_num_blocks, self->max_block_types_ + 1); + BROTLI_ENSURE_CAPACITY(m, uint8_t, + split->types, split->types_alloc_size, max_num_blocks); + BROTLI_ENSURE_CAPACITY(m, uint32_t, + split->lengths, split->lengths_alloc_size, max_num_blocks); + if (BROTLI_IS_OOM(m)) return; + split->num_blocks = max_num_blocks; + if (BROTLI_IS_OOM(m)) return; + BROTLI_DCHECK(*histograms == 0); + *histograms_size = max_num_types * num_contexts; + *histograms = BROTLI_ALLOC(m, HistogramLiteral, *histograms_size); + self->histograms_ = *histograms; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(*histograms)) return; + /* Clear only current histogram. */ + ClearHistogramsLiteral(&self->histograms_[0], num_contexts); + self->last_histogram_ix_[0] = self->last_histogram_ix_[1] = 0; +} + +/* Does either of three things: + (1) emits the current block with a new block type; + (2) emits the current block with the type of the second last block; + (3) merges the current block with the last block. */ +static void ContextBlockSplitterFinishBlock( + ContextBlockSplitter* self, MemoryManager* m, BROTLI_BOOL is_final) { + BlockSplit* split = self->split_; + const size_t num_contexts = self->num_contexts_; + double* last_entropy = self->last_entropy_; + HistogramLiteral* histograms = self->histograms_; + + if (self->block_size_ < self->min_block_size_) { + self->block_size_ = self->min_block_size_; + } + if (self->num_blocks_ == 0) { + size_t i; + /* Create first block. */ + split->lengths[0] = (uint32_t)self->block_size_; + split->types[0] = 0; + + for (i = 0; i < num_contexts; ++i) { + last_entropy[i] = + BrotliBitsEntropy(histograms[i].data_, self->alphabet_size_); + last_entropy[num_contexts + i] = last_entropy[i]; + } + ++self->num_blocks_; + ++split->num_types; + self->curr_histogram_ix_ += num_contexts; + if (self->curr_histogram_ix_ < *self->histograms_size_) { + ClearHistogramsLiteral( + &self->histograms_[self->curr_histogram_ix_], self->num_contexts_); + } + self->block_size_ = 0; + } else if (self->block_size_ > 0) { + /* Try merging the set of histograms for the current block type with the + respective set of histograms for the last and second last block types. + Decide over the split based on the total reduction of entropy across + all contexts. */ + double entropy[BROTLI_MAX_STATIC_CONTEXTS]; + HistogramLiteral* combined_histo = + BROTLI_ALLOC(m, HistogramLiteral, 2 * num_contexts); + double combined_entropy[2 * BROTLI_MAX_STATIC_CONTEXTS]; + double diff[2] = { 0.0 }; + size_t i; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(combined_histo)) return; + for (i = 0; i < num_contexts; ++i) { + size_t curr_histo_ix = self->curr_histogram_ix_ + i; + size_t j; + entropy[i] = BrotliBitsEntropy(histograms[curr_histo_ix].data_, + self->alphabet_size_); + for (j = 0; j < 2; ++j) { + size_t jx = j * num_contexts + i; + size_t last_histogram_ix = self->last_histogram_ix_[j] + i; + combined_histo[jx] = histograms[curr_histo_ix]; + HistogramAddHistogramLiteral(&combined_histo[jx], + &histograms[last_histogram_ix]); + combined_entropy[jx] = BrotliBitsEntropy( + &combined_histo[jx].data_[0], self->alphabet_size_); + diff[j] += combined_entropy[jx] - entropy[i] - last_entropy[jx]; + } + } + + if (split->num_types < self->max_block_types_ && + diff[0] > self->split_threshold_ && + diff[1] > self->split_threshold_) { + /* Create new block. */ + split->lengths[self->num_blocks_] = (uint32_t)self->block_size_; + split->types[self->num_blocks_] = (uint8_t)split->num_types; + self->last_histogram_ix_[1] = self->last_histogram_ix_[0]; + self->last_histogram_ix_[0] = split->num_types * num_contexts; + for (i = 0; i < num_contexts; ++i) { + last_entropy[num_contexts + i] = last_entropy[i]; + last_entropy[i] = entropy[i]; + } + ++self->num_blocks_; + ++split->num_types; + self->curr_histogram_ix_ += num_contexts; + if (self->curr_histogram_ix_ < *self->histograms_size_) { + ClearHistogramsLiteral( + &self->histograms_[self->curr_histogram_ix_], self->num_contexts_); + } + self->block_size_ = 0; + self->merge_last_count_ = 0; + self->target_block_size_ = self->min_block_size_; + } else if (diff[1] < diff[0] - 20.0) { + /* Combine this block with second last block. */ + split->lengths[self->num_blocks_] = (uint32_t)self->block_size_; + split->types[self->num_blocks_] = split->types[self->num_blocks_ - 2]; + BROTLI_SWAP(size_t, self->last_histogram_ix_, 0, 1); + for (i = 0; i < num_contexts; ++i) { + histograms[self->last_histogram_ix_[0] + i] = + combined_histo[num_contexts + i]; + last_entropy[num_contexts + i] = last_entropy[i]; + last_entropy[i] = combined_entropy[num_contexts + i]; + HistogramClearLiteral(&histograms[self->curr_histogram_ix_ + i]); + } + ++self->num_blocks_; + self->block_size_ = 0; + self->merge_last_count_ = 0; + self->target_block_size_ = self->min_block_size_; + } else { + /* Combine this block with last block. */ + split->lengths[self->num_blocks_ - 1] += (uint32_t)self->block_size_; + for (i = 0; i < num_contexts; ++i) { + histograms[self->last_histogram_ix_[0] + i] = combined_histo[i]; + last_entropy[i] = combined_entropy[i]; + if (split->num_types == 1) { + last_entropy[num_contexts + i] = last_entropy[i]; + } + HistogramClearLiteral(&histograms[self->curr_histogram_ix_ + i]); + } + self->block_size_ = 0; + if (++self->merge_last_count_ > 1) { + self->target_block_size_ += self->min_block_size_; + } + } + BROTLI_FREE(m, combined_histo); + } + if (is_final) { + *self->histograms_size_ = split->num_types * num_contexts; + split->num_blocks = self->num_blocks_; + } +} + +/* Adds the next symbol to the current block type and context. When the + current block reaches the target size, decides on merging the block. */ +static void ContextBlockSplitterAddSymbol( + ContextBlockSplitter* self, MemoryManager* m, + size_t symbol, size_t context) { + HistogramAddLiteral(&self->histograms_[self->curr_histogram_ix_ + context], + symbol); + ++self->block_size_; + if (self->block_size_ == self->target_block_size_) { + ContextBlockSplitterFinishBlock(self, m, /* is_final = */ BROTLI_FALSE); + if (BROTLI_IS_OOM(m)) return; + } +} + +static void MapStaticContexts(MemoryManager* m, + size_t num_contexts, + const uint32_t* static_context_map, + MetaBlockSplit* mb) { + size_t i; + BROTLI_DCHECK(mb->literal_context_map == 0); + mb->literal_context_map_size = + mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS; + mb->literal_context_map = + BROTLI_ALLOC(m, uint32_t, mb->literal_context_map_size); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(mb->literal_context_map)) return; + + for (i = 0; i < mb->literal_split.num_types; ++i) { + uint32_t offset = (uint32_t)(i * num_contexts); + size_t j; + for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS); ++j) { + mb->literal_context_map[(i << BROTLI_LITERAL_CONTEXT_BITS) + j] = + offset + static_context_map[j]; + } + } +} + +typedef struct GreedyMetablockArena { + union { + BlockSplitterLiteral plain; + ContextBlockSplitter ctx; + } lit_blocks; + BlockSplitterCommand cmd_blocks; + BlockSplitterDistance dist_blocks; +} GreedyMetablockArena; + +static BROTLI_INLINE void BrotliBuildMetaBlockGreedyInternal( + MemoryManager* m, GreedyMetablockArena* arena, const uint8_t* ringbuffer, + size_t pos, size_t mask, uint8_t prev_byte, uint8_t prev_byte2, + ContextLut literal_context_lut, const size_t num_contexts, + const uint32_t* static_context_map, const Command* commands, + size_t n_commands, MetaBlockSplit* mb) { + size_t num_literals = 0; + size_t i; + for (i = 0; i < n_commands; ++i) { + num_literals += commands[i].insert_len_; + } + + if (num_contexts == 1) { + InitBlockSplitterLiteral(m, &arena->lit_blocks.plain, 256, 512, 400.0, + num_literals, &mb->literal_split, &mb->literal_histograms, + &mb->literal_histograms_size); + } else { + InitContextBlockSplitter(m, &arena->lit_blocks.ctx, 256, num_contexts, 512, + 400.0, num_literals, &mb->literal_split, &mb->literal_histograms, + &mb->literal_histograms_size); + } + if (BROTLI_IS_OOM(m)) return; + InitBlockSplitterCommand(m, &arena->cmd_blocks, BROTLI_NUM_COMMAND_SYMBOLS, + 1024, 500.0, n_commands, &mb->command_split, &mb->command_histograms, + &mb->command_histograms_size); + if (BROTLI_IS_OOM(m)) return; + InitBlockSplitterDistance(m, &arena->dist_blocks, 64, 512, 100.0, n_commands, + &mb->distance_split, &mb->distance_histograms, + &mb->distance_histograms_size); + if (BROTLI_IS_OOM(m)) return; + + for (i = 0; i < n_commands; ++i) { + const Command cmd = commands[i]; + size_t j; + BlockSplitterAddSymbolCommand(&arena->cmd_blocks, cmd.cmd_prefix_); + for (j = cmd.insert_len_; j != 0; --j) { + uint8_t literal = ringbuffer[pos & mask]; + if (num_contexts == 1) { + BlockSplitterAddSymbolLiteral(&arena->lit_blocks.plain, literal); + } else { + size_t context = + BROTLI_CONTEXT(prev_byte, prev_byte2, literal_context_lut); + ContextBlockSplitterAddSymbol(&arena->lit_blocks.ctx, m, literal, + static_context_map[context]); + if (BROTLI_IS_OOM(m)) return; + } + prev_byte2 = prev_byte; + prev_byte = literal; + ++pos; + } + pos += CommandCopyLen(&cmd); + if (CommandCopyLen(&cmd)) { + prev_byte2 = ringbuffer[(pos - 2) & mask]; + prev_byte = ringbuffer[(pos - 1) & mask]; + if (cmd.cmd_prefix_ >= 128) { + BlockSplitterAddSymbolDistance( + &arena->dist_blocks, cmd.dist_prefix_ & 0x3FF); + } + } + } + + if (num_contexts == 1) { + BlockSplitterFinishBlockLiteral( + &arena->lit_blocks.plain, /* is_final = */ BROTLI_TRUE); + } else { + ContextBlockSplitterFinishBlock( + &arena->lit_blocks.ctx, m, /* is_final = */ BROTLI_TRUE); + if (BROTLI_IS_OOM(m)) return; + } + BlockSplitterFinishBlockCommand( + &arena->cmd_blocks, /* is_final = */ BROTLI_TRUE); + BlockSplitterFinishBlockDistance( + &arena->dist_blocks, /* is_final = */ BROTLI_TRUE); + + if (num_contexts > 1) { + MapStaticContexts(m, num_contexts, static_context_map, mb); + } +} + +void BrotliBuildMetaBlockGreedy(MemoryManager* m, + const uint8_t* ringbuffer, + size_t pos, + size_t mask, + uint8_t prev_byte, + uint8_t prev_byte2, + ContextLut literal_context_lut, + size_t num_contexts, + const uint32_t* static_context_map, + const Command* commands, + size_t n_commands, + MetaBlockSplit* mb) { + GreedyMetablockArena* arena = BROTLI_ALLOC(m, GreedyMetablockArena, 1); + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(arena)) return; + if (num_contexts == 1) { + BrotliBuildMetaBlockGreedyInternal(m, arena, ringbuffer, pos, mask, + prev_byte, prev_byte2, literal_context_lut, 1, NULL, commands, + n_commands, mb); + } else { + BrotliBuildMetaBlockGreedyInternal(m, arena, ringbuffer, pos, mask, + prev_byte, prev_byte2, literal_context_lut, num_contexts, + static_context_map, commands, n_commands, mb); + } + BROTLI_FREE(m, arena); +} + +void BrotliOptimizeHistograms(uint32_t num_distance_codes, + MetaBlockSplit* mb) { + uint8_t good_for_rle[BROTLI_NUM_COMMAND_SYMBOLS]; + size_t i; + for (i = 0; i < mb->literal_histograms_size; ++i) { + BrotliOptimizeHuffmanCountsForRle(256, mb->literal_histograms[i].data_, + good_for_rle); + } + for (i = 0; i < mb->command_histograms_size; ++i) { + BrotliOptimizeHuffmanCountsForRle(BROTLI_NUM_COMMAND_SYMBOLS, + mb->command_histograms[i].data_, + good_for_rle); + } + for (i = 0; i < mb->distance_histograms_size; ++i) { + BrotliOptimizeHuffmanCountsForRle(num_distance_codes, + mb->distance_histograms[i].data_, + good_for_rle); + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/metablock.h b/packages/runtime/vendor/brotli/c/enc/metablock.h new file mode 100644 index 000000000..e7d10526d --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/metablock.h @@ -0,0 +1,106 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Algorithms for distributing the literals and commands of a metablock between + block types and contexts. */ + +#ifndef BROTLI_ENC_METABLOCK_H_ +#define BROTLI_ENC_METABLOCK_H_ + +#include "../common/context.h" +#include "../common/platform.h" +#include "block_splitter.h" +#include "command.h" +#include "histogram.h" +#include "memory.h" +#include "params.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define BROTLI_MAX_STATIC_CONTEXTS 13 + +typedef struct MetaBlockSplit { + BlockSplit literal_split; + BlockSplit command_split; + BlockSplit distance_split; + uint32_t* literal_context_map; + size_t literal_context_map_size; + uint32_t* distance_context_map; + size_t distance_context_map_size; + HistogramLiteral* literal_histograms; + size_t literal_histograms_size; + HistogramCommand* command_histograms; + size_t command_histograms_size; + HistogramDistance* distance_histograms; + size_t distance_histograms_size; +} MetaBlockSplit; + +static BROTLI_INLINE void InitMetaBlockSplit(MetaBlockSplit* mb) { + BrotliInitBlockSplit(&mb->literal_split); + BrotliInitBlockSplit(&mb->command_split); + BrotliInitBlockSplit(&mb->distance_split); + mb->literal_context_map = 0; + mb->literal_context_map_size = 0; + mb->distance_context_map = 0; + mb->distance_context_map_size = 0; + mb->literal_histograms = 0; + mb->literal_histograms_size = 0; + mb->command_histograms = 0; + mb->command_histograms_size = 0; + mb->distance_histograms = 0; + mb->distance_histograms_size = 0; +} + +static BROTLI_INLINE void DestroyMetaBlockSplit( + MemoryManager* m, MetaBlockSplit* mb) { + BrotliDestroyBlockSplit(m, &mb->literal_split); + BrotliDestroyBlockSplit(m, &mb->command_split); + BrotliDestroyBlockSplit(m, &mb->distance_split); + BROTLI_FREE(m, mb->literal_context_map); + BROTLI_FREE(m, mb->distance_context_map); + BROTLI_FREE(m, mb->literal_histograms); + BROTLI_FREE(m, mb->command_histograms); + BROTLI_FREE(m, mb->distance_histograms); +} + +/* Uses the slow shortest-path block splitter and does context clustering. + The distance parameters are dynamically selected based on the commands + which get recomputed under the new distance parameters. The new distance + parameters are stored into *params. */ +BROTLI_INTERNAL void BrotliBuildMetaBlock(MemoryManager* m, + const uint8_t* ringbuffer, + const size_t pos, + const size_t mask, + BrotliEncoderParams* params, + uint8_t prev_byte, + uint8_t prev_byte2, + Command* cmds, + size_t num_commands, + ContextType literal_context_mode, + MetaBlockSplit* mb); + +/* Uses a fast greedy block splitter that tries to merge current block with the + last or the second last block and uses a static context clustering which + is the same for all block types. */ +BROTLI_INTERNAL void BrotliBuildMetaBlockGreedy( + MemoryManager* m, const uint8_t* ringbuffer, size_t pos, size_t mask, + uint8_t prev_byte, uint8_t prev_byte2, ContextLut literal_context_lut, + size_t num_contexts, const uint32_t* static_context_map, + const Command* commands, size_t n_commands, MetaBlockSplit* mb); + +BROTLI_INTERNAL void BrotliOptimizeHistograms(uint32_t num_distance_codes, + MetaBlockSplit* mb); + +BROTLI_INTERNAL void BrotliInitDistanceParams(BrotliDistanceParams* params, + uint32_t npostfix, uint32_t ndirect, BROTLI_BOOL large_window); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_METABLOCK_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/metablock_inc.h b/packages/runtime/vendor/brotli/c/enc/metablock_inc.h new file mode 100644 index 000000000..e7a7bc821 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/metablock_inc.h @@ -0,0 +1,185 @@ +/* NOLINT(build/header_guard) */ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* template parameters: FN */ + +#define HistogramType FN(Histogram) + +/* Greedy block splitter for one block category (literal, command or distance). +*/ +typedef struct FN(BlockSplitter) { + /* Alphabet size of particular block category. */ + size_t alphabet_size_; + /* We collect at least this many symbols for each block. */ + size_t min_block_size_; + /* We merge histograms A and B if + entropy(A+B) < entropy(A) + entropy(B) + split_threshold_, + where A is the current histogram and B is the histogram of the last or the + second last block type. */ + double split_threshold_; + + size_t num_blocks_; + BlockSplit* split_; /* not owned */ + HistogramType* histograms_; /* not owned */ + size_t* histograms_size_; /* not owned */ + + /* Temporary storage for BlockSplitterFinishBlock. */ + HistogramType combined_histo[2]; + + /* The number of symbols that we want to collect before deciding on whether + or not to merge the block with a previous one or emit a new block. */ + size_t target_block_size_; + /* The number of symbols in the current histogram. */ + size_t block_size_; + /* Offset of the current histogram. */ + size_t curr_histogram_ix_; + /* Offset of the histograms of the previous two block types. */ + size_t last_histogram_ix_[2]; + /* Entropy of the previous two block types. */ + double last_entropy_[2]; + /* The number of times we merged the current block with the last one. */ + size_t merge_last_count_; +} FN(BlockSplitter); + +static void FN(InitBlockSplitter)( + MemoryManager* m, FN(BlockSplitter)* self, size_t alphabet_size, + size_t min_block_size, double split_threshold, size_t num_symbols, + BlockSplit* split, HistogramType** histograms, size_t* histograms_size) { + size_t max_num_blocks = num_symbols / min_block_size + 1; + /* We have to allocate one more histogram than the maximum number of block + types for the current histogram when the meta-block is too big. */ + size_t max_num_types = + BROTLI_MIN(size_t, max_num_blocks, BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + 1); + self->alphabet_size_ = alphabet_size; + self->min_block_size_ = min_block_size; + self->split_threshold_ = split_threshold; + self->num_blocks_ = 0; + self->split_ = split; + self->histograms_size_ = histograms_size; + self->target_block_size_ = min_block_size; + self->block_size_ = 0; + self->curr_histogram_ix_ = 0; + self->merge_last_count_ = 0; + BROTLI_ENSURE_CAPACITY(m, uint8_t, + split->types, split->types_alloc_size, max_num_blocks); + BROTLI_ENSURE_CAPACITY(m, uint32_t, + split->lengths, split->lengths_alloc_size, max_num_blocks); + if (BROTLI_IS_OOM(m)) return; + self->split_->num_blocks = max_num_blocks; + BROTLI_DCHECK(*histograms == 0); + *histograms_size = max_num_types; + *histograms = BROTLI_ALLOC(m, HistogramType, *histograms_size); + self->histograms_ = *histograms; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(*histograms)) return; + /* Clear only current histogram. */ + FN(HistogramClear)(&self->histograms_[0]); + self->last_histogram_ix_[0] = self->last_histogram_ix_[1] = 0; +} + +/* Does either of three things: + (1) emits the current block with a new block type; + (2) emits the current block with the type of the second last block; + (3) merges the current block with the last block. */ +static void FN(BlockSplitterFinishBlock)( + FN(BlockSplitter)* self, BROTLI_BOOL is_final) { + BlockSplit* split = self->split_; + double* last_entropy = self->last_entropy_; + HistogramType* histograms = self->histograms_; + self->block_size_ = + BROTLI_MAX(size_t, self->block_size_, self->min_block_size_); + if (self->num_blocks_ == 0) { + /* Create first block. */ + split->lengths[0] = (uint32_t)self->block_size_; + split->types[0] = 0; + last_entropy[0] = + BrotliBitsEntropy(histograms[0].data_, self->alphabet_size_); + last_entropy[1] = last_entropy[0]; + ++self->num_blocks_; + ++split->num_types; + ++self->curr_histogram_ix_; + if (self->curr_histogram_ix_ < *self->histograms_size_) + FN(HistogramClear)(&histograms[self->curr_histogram_ix_]); + self->block_size_ = 0; + } else if (self->block_size_ > 0) { + double entropy = BrotliBitsEntropy( + histograms[self->curr_histogram_ix_].data_, self->alphabet_size_); + double combined_entropy[2]; + double diff[2]; + size_t j; + for (j = 0; j < 2; ++j) { + size_t last_histogram_ix = self->last_histogram_ix_[j]; + self->combined_histo[j] = histograms[self->curr_histogram_ix_]; + FN(HistogramAddHistogram)(&self->combined_histo[j], + &histograms[last_histogram_ix]); + combined_entropy[j] = BrotliBitsEntropy( + &self->combined_histo[j].data_[0], self->alphabet_size_); + diff[j] = combined_entropy[j] - entropy - last_entropy[j]; + } + + if (split->num_types < BROTLI_MAX_NUMBER_OF_BLOCK_TYPES && + diff[0] > self->split_threshold_ && + diff[1] > self->split_threshold_) { + /* Create new block. */ + split->lengths[self->num_blocks_] = (uint32_t)self->block_size_; + split->types[self->num_blocks_] = (uint8_t)split->num_types; + self->last_histogram_ix_[1] = self->last_histogram_ix_[0]; + self->last_histogram_ix_[0] = (uint8_t)split->num_types; + last_entropy[1] = last_entropy[0]; + last_entropy[0] = entropy; + ++self->num_blocks_; + ++split->num_types; + ++self->curr_histogram_ix_; + if (self->curr_histogram_ix_ < *self->histograms_size_) + FN(HistogramClear)(&histograms[self->curr_histogram_ix_]); + self->block_size_ = 0; + self->merge_last_count_ = 0; + self->target_block_size_ = self->min_block_size_; + } else if (diff[1] < diff[0] - 20.0) { + /* Combine this block with second last block. */ + split->lengths[self->num_blocks_] = (uint32_t)self->block_size_; + split->types[self->num_blocks_] = split->types[self->num_blocks_ - 2]; + BROTLI_SWAP(size_t, self->last_histogram_ix_, 0, 1); + histograms[self->last_histogram_ix_[0]] = self->combined_histo[1]; + last_entropy[1] = last_entropy[0]; + last_entropy[0] = combined_entropy[1]; + ++self->num_blocks_; + self->block_size_ = 0; + FN(HistogramClear)(&histograms[self->curr_histogram_ix_]); + self->merge_last_count_ = 0; + self->target_block_size_ = self->min_block_size_; + } else { + /* Combine this block with last block. */ + split->lengths[self->num_blocks_ - 1] += (uint32_t)self->block_size_; + histograms[self->last_histogram_ix_[0]] = self->combined_histo[0]; + last_entropy[0] = combined_entropy[0]; + if (split->num_types == 1) { + last_entropy[1] = last_entropy[0]; + } + self->block_size_ = 0; + FN(HistogramClear)(&histograms[self->curr_histogram_ix_]); + if (++self->merge_last_count_ > 1) { + self->target_block_size_ += self->min_block_size_; + } + } + } + if (is_final) { + *self->histograms_size_ = split->num_types; + split->num_blocks = self->num_blocks_; + } +} + +/* Adds the next symbol to the current histogram. When the current histogram + reaches the target size, decides on merging the block. */ +static void FN(BlockSplitterAddSymbol)(FN(BlockSplitter)* self, size_t symbol) { + FN(HistogramAdd)(&self->histograms_[self->curr_histogram_ix_], symbol); + ++self->block_size_; + if (self->block_size_ == self->target_block_size_) { + FN(BlockSplitterFinishBlock)(self, /* is_final = */ BROTLI_FALSE); + } +} + +#undef HistogramType diff --git a/packages/runtime/vendor/brotli/c/enc/params.h b/packages/runtime/vendor/brotli/c/enc/params.h new file mode 100644 index 000000000..fd1de0096 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/params.h @@ -0,0 +1,46 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Parameters for the Brotli encoder with chosen quality levels. */ + +#ifndef BROTLI_ENC_PARAMS_H_ +#define BROTLI_ENC_PARAMS_H_ + +#include +#include "encoder_dict.h" + +typedef struct BrotliHasherParams { + int type; + int bucket_bits; + int block_bits; + int num_last_distances_to_check; +} BrotliHasherParams; + +typedef struct BrotliDistanceParams { + uint32_t distance_postfix_bits; + uint32_t num_direct_distance_codes; + uint32_t alphabet_size_max; + uint32_t alphabet_size_limit; + size_t max_distance; +} BrotliDistanceParams; + +/* Encoding parameters */ +typedef struct BrotliEncoderParams { + BrotliEncoderMode mode; + int quality; + int lgwin; + int lgblock; + size_t stream_offset; + size_t size_hint; + BROTLI_BOOL disable_literal_context_modeling; + BROTLI_BOOL large_window; + BrotliHasherParams hasher; + BrotliDistanceParams dist; + /* TODO(eustas): rename to BrotliShared... */ + SharedEncoderDictionary dictionary; +} BrotliEncoderParams; + +#endif /* BROTLI_ENC_PARAMS_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/prefix.h b/packages/runtime/vendor/brotli/c/enc/prefix.h new file mode 100644 index 000000000..24c0afc17 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/prefix.h @@ -0,0 +1,52 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Functions for encoding of integers into prefix codes the amount of extra + bits, and the actual values of the extra bits. */ + +#ifndef BROTLI_ENC_PREFIX_H_ +#define BROTLI_ENC_PREFIX_H_ + +#include "../common/constants.h" +#include "../common/platform.h" +#include "fast_log.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* Here distance_code is an intermediate code, i.e. one of the special codes or + the actual distance increased by BROTLI_NUM_DISTANCE_SHORT_CODES - 1. */ +static BROTLI_INLINE void PrefixEncodeCopyDistance(size_t distance_code, + size_t num_direct_codes, + size_t postfix_bits, + uint16_t* code, + uint32_t* extra_bits) { + if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES + num_direct_codes) { + *code = (uint16_t)distance_code; + *extra_bits = 0; + return; + } else { + size_t dist = ((size_t)1 << (postfix_bits + 2u)) + + (distance_code - BROTLI_NUM_DISTANCE_SHORT_CODES - num_direct_codes); + size_t bucket = Log2FloorNonZero(dist) - 1; + size_t postfix_mask = (1u << postfix_bits) - 1; + size_t postfix = dist & postfix_mask; + size_t prefix = (dist >> bucket) & 1; + size_t offset = (2 + prefix) << bucket; + size_t nbits = bucket - postfix_bits; + *code = (uint16_t)((nbits << 10) | + (BROTLI_NUM_DISTANCE_SHORT_CODES + num_direct_codes + + ((2 * (nbits - 1) + prefix) << postfix_bits) + postfix)); + *extra_bits = (uint32_t)((dist - offset) >> postfix_bits); + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_PREFIX_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/quality.h b/packages/runtime/vendor/brotli/c/enc/quality.h new file mode 100644 index 000000000..45d67bf40 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/quality.h @@ -0,0 +1,209 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Constants and formulas that affect speed-ratio trade-offs and thus define + quality levels. */ + +#ifndef BROTLI_ENC_QUALITY_H_ +#define BROTLI_ENC_QUALITY_H_ + +#include "../common/platform.h" +#include +#include "params.h" + +#define FAST_ONE_PASS_COMPRESSION_QUALITY 0 +#define FAST_TWO_PASS_COMPRESSION_QUALITY 1 +#define ZOPFLIFICATION_QUALITY 10 +#define HQ_ZOPFLIFICATION_QUALITY 11 + +#define MAX_QUALITY_FOR_STATIC_ENTROPY_CODES 2 +#define MIN_QUALITY_FOR_BLOCK_SPLIT 4 +#define MIN_QUALITY_FOR_NONZERO_DISTANCE_PARAMS 4 +#define MIN_QUALITY_FOR_OPTIMIZE_HISTOGRAMS 4 +#define MIN_QUALITY_FOR_EXTENSIVE_REFERENCE_SEARCH 5 +#define MIN_QUALITY_FOR_CONTEXT_MODELING 5 +#define MIN_QUALITY_FOR_HQ_CONTEXT_MODELING 7 +#define MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING 10 + +/* For quality below MIN_QUALITY_FOR_BLOCK_SPLIT there is no block splitting, + so we buffer at most this much literals and commands. */ +#define MAX_NUM_DELAYED_SYMBOLS 0x2FFF + +/* Returns hash-table size for quality levels 0 and 1. */ +static BROTLI_INLINE size_t MaxHashTableSize(int quality) { + return quality == FAST_ONE_PASS_COMPRESSION_QUALITY ? 1 << 15 : 1 << 17; +} + +/* The maximum length for which the zopflification uses distinct distances. */ +#define MAX_ZOPFLI_LEN_QUALITY_10 150 +#define MAX_ZOPFLI_LEN_QUALITY_11 325 + +/* Do not thoroughly search when a long copy is found. */ +#define BROTLI_LONG_COPY_QUICK_STEP 16384 + +static BROTLI_INLINE size_t MaxZopfliLen(const BrotliEncoderParams* params) { + return params->quality <= 10 ? + MAX_ZOPFLI_LEN_QUALITY_10 : + MAX_ZOPFLI_LEN_QUALITY_11; +} + +/* Number of best candidates to evaluate to expand Zopfli chain. */ +static BROTLI_INLINE size_t MaxZopfliCandidates( + const BrotliEncoderParams* params) { + return params->quality <= 10 ? 1 : 5; +} + +static BROTLI_INLINE void SanitizeParams(BrotliEncoderParams* params) { + params->quality = BROTLI_MIN(int, BROTLI_MAX_QUALITY, + BROTLI_MAX(int, BROTLI_MIN_QUALITY, params->quality)); + if (params->quality <= MAX_QUALITY_FOR_STATIC_ENTROPY_CODES) { + params->large_window = BROTLI_FALSE; + } + if (params->lgwin < BROTLI_MIN_WINDOW_BITS) { + params->lgwin = BROTLI_MIN_WINDOW_BITS; + } else { + int max_lgwin = params->large_window ? BROTLI_LARGE_MAX_WINDOW_BITS : + BROTLI_MAX_WINDOW_BITS; + if (params->lgwin > max_lgwin) params->lgwin = max_lgwin; + } +} + +/* Returns optimized lg_block value. */ +static BROTLI_INLINE int ComputeLgBlock(const BrotliEncoderParams* params) { + int lgblock = params->lgblock; + if (params->quality == FAST_ONE_PASS_COMPRESSION_QUALITY || + params->quality == FAST_TWO_PASS_COMPRESSION_QUALITY) { + lgblock = params->lgwin; + } else if (params->quality < MIN_QUALITY_FOR_BLOCK_SPLIT) { + lgblock = 14; + } else if (lgblock == 0) { + lgblock = 16; + if (params->quality >= 9 && params->lgwin > lgblock) { + lgblock = BROTLI_MIN(int, 18, params->lgwin); + } + } else { + lgblock = BROTLI_MIN(int, BROTLI_MAX_INPUT_BLOCK_BITS, + BROTLI_MAX(int, BROTLI_MIN_INPUT_BLOCK_BITS, lgblock)); + } + return lgblock; +} + +/* Returns log2 of the size of main ring buffer area. + Allocate at least lgwin + 1 bits for the ring buffer so that the newly + added block fits there completely and we still get lgwin bits and at least + read_block_size_bits + 1 bits because the copy tail length needs to be + smaller than ring-buffer size. */ +static BROTLI_INLINE int ComputeRbBits(const BrotliEncoderParams* params) { + return 1 + BROTLI_MAX(int, params->lgwin, params->lgblock); +} + +static BROTLI_INLINE size_t MaxMetablockSize( + const BrotliEncoderParams* params) { + int bits = + BROTLI_MIN(int, ComputeRbBits(params), BROTLI_MAX_INPUT_BLOCK_BITS); + return (size_t)1 << bits; +} + +/* When searching for backward references and have not seen matches for a long + time, we can skip some match lookups. Unsuccessful match lookups are very + expensive and this kind of a heuristic speeds up compression quite a lot. + At first 8 byte strides are taken and every second byte is put to hasher. + After 4x more literals stride by 16 bytes, every put 4-th byte to hasher. + Applied only to qualities 2 to 9. */ +static BROTLI_INLINE size_t LiteralSpreeLengthForSparseSearch( + const BrotliEncoderParams* params) { + return params->quality < 9 ? 64 : 512; +} + +/* Quality to hasher mapping: + + - q02: h02 (longest_match_quickly), b16, l5 + + - q03: h03 (longest_match_quickly), b17, l5 + + - q04: h04 (longest_match_quickly), b17, l5 + - q04: h54 (longest_match_quickly), b20, l7 | for large files + + - q05: h58 (longest_match_simd ), b14, l4 + - q05: h68 (longest_match64_simd ), b15, l5 | for large files + - q05: h40 (forgetful_chain ), b15, l4 | for small window + + - q06: h58 (longest_match_simd ), b14, l4 + - q06: h68 (longest_match64_simd ), b15, l5 | for large files + - q06: h40 (forgetful_chain ), b15, l4 | for small window + + - q07: h58 (longest_match_simd ), b15, l4 + - q07: h68 (longest_match64_simd ), b15, l5 | for large files + - q07: h41 (forgetful_chain ), b15, l4 | for small window + + - q08: h05 (longest_match ), b15, l4 + - q08: h06 (longest_match64 ), b15, l5 | for large files + - q08: h41 (forgetful_chain ), b15, l4 | for small window + + - q09: h05 (longest_match ), b15, l4 + - q09: h06 (longest_match64 ), b15, l5 | for large files + - q09: h42 (forgetful_chain ), b15, l4 | for small window + + - q10: t10 (to_binary_tree ), b17, l128 + + - q11: t10 (to_binary_tree ), b17, l128 + + Where "q" is quality, "h" is hasher type, "b" is bucket bits, + "l" is source len. */ +static BROTLI_INLINE void ChooseHasher(const BrotliEncoderParams* params, + BrotliHasherParams* hparams) { + if (params->quality > 9) { + hparams->type = 10; + } else if (params->quality == 4 && params->size_hint >= (1 << 20)) { + hparams->type = 54; + } else if (params->quality < 5) { + hparams->type = params->quality; + } else if (params->lgwin <= 16) { + hparams->type = params->quality < 7 ? 40 : params->quality < 9 ? 41 : 42; + } else if (params->size_hint >= (1 << 20) && params->lgwin >= 19) { +#if defined(BROTLI_MAX_SIMD_QUALITY) + hparams->type = params->quality <= BROTLI_MAX_SIMD_QUALITY ? 68 : 6; +#else + hparams->type = 6; +#endif + hparams->block_bits = params->quality - 1; + hparams->bucket_bits = 15; + hparams->num_last_distances_to_check = + params->quality < 7 ? 4 : params->quality < 9 ? 10 : 16; + } else { + /* TODO(eustas): often previous setting (H6) is faster and denser; consider + adding an option to use it. */ +#if defined(BROTLI_MAX_SIMD_QUALITY) + hparams->type = params->quality <= BROTLI_MAX_SIMD_QUALITY ? 58 : 5; +#else + hparams->type = 5; +#endif + hparams->block_bits = params->quality - 1; + hparams->bucket_bits = params->quality < 7 ? 14 : 15; + hparams->num_last_distances_to_check = + params->quality < 7 ? 4 : params->quality < 9 ? 10 : 16; + } + + if (params->lgwin > 24) { + /* Different hashers for large window brotli: not for qualities <= 2, + these are too fast for large window. Not for qualities >= 10: their + hasher already works well with large window. So the changes are: + H3 --> H35: for quality 3. + H54 --> H55: for quality 4 with size hint > 1MB + H6/H68 --> H65: for qualities 5, 6, 7, 8, 9. */ + if (hparams->type == 3) { + hparams->type = 35; + } + if (hparams->type == 54) { + hparams->type = 55; + } + if (hparams->type == 6 || hparams->type == 68) { + hparams->type = 65; + } + } +} + +#endif /* BROTLI_ENC_QUALITY_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/ringbuffer.h b/packages/runtime/vendor/brotli/c/enc/ringbuffer.h new file mode 100644 index 000000000..5bb75ed7c --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/ringbuffer.h @@ -0,0 +1,165 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Sliding window over the input data. */ + +#ifndef BROTLI_ENC_RINGBUFFER_H_ +#define BROTLI_ENC_RINGBUFFER_H_ + +#include "../common/platform.h" +#include "memory.h" +#include "params.h" +#include "quality.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* A RingBuffer(window_bits, tail_bits) contains `1 << window_bits' bytes of + data in a circular manner: writing a byte writes it to: + `position() % (1 << window_bits)'. + For convenience, the RingBuffer array contains another copy of the + first `1 << tail_bits' bytes: + buffer_[i] == buffer_[i + (1 << window_bits)], if i < (1 << tail_bits), + and another copy of the last two bytes: + buffer_[-1] == buffer_[(1 << window_bits) - 1] and + buffer_[-2] == buffer_[(1 << window_bits) - 2]. */ +typedef struct RingBuffer { + /* Size of the ring-buffer is (1 << window_bits) + tail_size_. */ + const uint32_t size_; + const uint32_t mask_; + const uint32_t tail_size_; + const uint32_t total_size_; + + uint32_t cur_size_; + /* Position to write in the ring buffer. */ + uint32_t pos_; + /* The actual ring buffer containing the copy of the last two bytes, the data, + and the copy of the beginning as a tail. */ + uint8_t* data_; + /* The start of the ring-buffer. */ + uint8_t* buffer_; +} RingBuffer; + +static BROTLI_INLINE void RingBufferInit(RingBuffer* rb) { + rb->cur_size_ = 0; + rb->pos_ = 0; + rb->data_ = 0; + rb->buffer_ = 0; +} + +static BROTLI_INLINE void RingBufferSetup( + const BrotliEncoderParams* params, RingBuffer* rb) { + int window_bits = ComputeRbBits(params); + int tail_bits = params->lgblock; + *(uint32_t*)&rb->size_ = 1u << window_bits; + *(uint32_t*)&rb->mask_ = (1u << window_bits) - 1; + *(uint32_t*)&rb->tail_size_ = 1u << tail_bits; + *(uint32_t*)&rb->total_size_ = rb->size_ + rb->tail_size_; +} + +static BROTLI_INLINE void RingBufferFree(MemoryManager* m, RingBuffer* rb) { + BROTLI_FREE(m, rb->data_); +} + +/* Allocates or re-allocates data_ to the given length + plus some slack + region before and after. Fills the slack regions with zeros. */ +static BROTLI_INLINE void RingBufferInitBuffer( + MemoryManager* m, const uint32_t buflen, RingBuffer* rb) { + static const size_t kSlackForEightByteHashingEverywhere = 7; + uint8_t* new_data = BROTLI_ALLOC( + m, uint8_t, 2 + buflen + kSlackForEightByteHashingEverywhere); + size_t i; + if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(new_data)) return; + if (rb->data_) { + memcpy(new_data, rb->data_, + 2 + rb->cur_size_ + kSlackForEightByteHashingEverywhere); + BROTLI_FREE(m, rb->data_); + } + rb->data_ = new_data; + rb->cur_size_ = buflen; + rb->buffer_ = rb->data_ + 2; + rb->buffer_[-2] = rb->buffer_[-1] = 0; + for (i = 0; i < kSlackForEightByteHashingEverywhere; ++i) { + rb->buffer_[rb->cur_size_ + i] = 0; + } +} + +static BROTLI_INLINE void RingBufferWriteTail( + const uint8_t* bytes, size_t n, RingBuffer* rb) { + const size_t masked_pos = rb->pos_ & rb->mask_; + if (BROTLI_PREDICT_FALSE(masked_pos < rb->tail_size_)) { + /* Just fill the tail buffer with the beginning data. */ + const size_t p = rb->size_ + masked_pos; + memcpy(&rb->buffer_[p], bytes, + BROTLI_MIN(size_t, n, rb->tail_size_ - masked_pos)); + } +} + +/* Push bytes into the ring buffer. */ +static BROTLI_INLINE void RingBufferWrite( + MemoryManager* m, const uint8_t* bytes, size_t n, RingBuffer* rb) { + if (rb->pos_ == 0 && n < rb->tail_size_) { + /* Special case for the first write: to process the first block, we don't + need to allocate the whole ring-buffer and we don't need the tail + either. However, we do this memory usage optimization only if the + first write is less than the tail size, which is also the input block + size, otherwise it is likely that other blocks will follow and we + will need to reallocate to the full size anyway. */ + rb->pos_ = (uint32_t)n; + RingBufferInitBuffer(m, rb->pos_, rb); + if (BROTLI_IS_OOM(m)) return; + memcpy(rb->buffer_, bytes, n); + return; + } + if (rb->cur_size_ < rb->total_size_) { + /* Lazily allocate the full buffer. */ + RingBufferInitBuffer(m, rb->total_size_, rb); + if (BROTLI_IS_OOM(m)) return; + /* Initialize the last two bytes to zero, so that we don't have to worry + later when we copy the last two bytes to the first two positions. */ + rb->buffer_[rb->size_ - 2] = 0; + rb->buffer_[rb->size_ - 1] = 0; + /* Initialize tail; might be touched by "best_len++" optimization when + ring buffer is "full". */ + rb->buffer_[rb->size_] = 241; + } + { + const size_t masked_pos = rb->pos_ & rb->mask_; + /* The length of the writes is limited so that we do not need to worry + about a write */ + RingBufferWriteTail(bytes, n, rb); + if (BROTLI_PREDICT_TRUE(masked_pos + n <= rb->size_)) { + /* A single write fits. */ + memcpy(&rb->buffer_[masked_pos], bytes, n); + } else { + /* Split into two writes. + Copy into the end of the buffer, including the tail buffer. */ + memcpy(&rb->buffer_[masked_pos], bytes, + BROTLI_MIN(size_t, n, rb->total_size_ - masked_pos)); + /* Copy into the beginning of the buffer */ + memcpy(&rb->buffer_[0], bytes + (rb->size_ - masked_pos), + n - (rb->size_ - masked_pos)); + } + } + { + BROTLI_BOOL not_first_lap = (rb->pos_ & (1u << 31)) != 0; + uint32_t rb_pos_mask = (1u << 31) - 1; + rb->buffer_[-2] = rb->buffer_[rb->size_ - 2]; + rb->buffer_[-1] = rb->buffer_[rb->size_ - 1]; + rb->pos_ = (rb->pos_ & rb_pos_mask) + (uint32_t)(n & rb_pos_mask); + if (not_first_lap) { + /* Wrap, but preserve not-a-first-lap feature. */ + rb->pos_ |= 1u << 31; + } + } +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_RINGBUFFER_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/state.h b/packages/runtime/vendor/brotli/c/enc/state.h new file mode 100644 index 000000000..325f9f3dd --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/state.h @@ -0,0 +1,104 @@ +/* Copyright 2022 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Encoder state. */ + +#ifndef BROTLI_ENC_STATE_H_ +#define BROTLI_ENC_STATE_H_ + +#include "../common/constants.h" +#include "../common/platform.h" +#include "command.h" +#include "compress_fragment.h" +#include "compress_fragment_two_pass.h" +#include "hash.h" +#include "memory.h" +#include "params.h" +#include "ringbuffer.h" + +typedef enum BrotliEncoderStreamState { + /* Default state. */ + BROTLI_STREAM_PROCESSING = 0, + /* Intermediate state; after next block is emitted, byte-padding should be + performed before getting back to default state. */ + BROTLI_STREAM_FLUSH_REQUESTED = 1, + /* Last metablock was produced; no more input is acceptable. */ + BROTLI_STREAM_FINISHED = 2, + /* Flushing compressed block and writing meta-data block header. */ + BROTLI_STREAM_METADATA_HEAD = 3, + /* Writing metadata block body. */ + BROTLI_STREAM_METADATA_BODY = 4 +} BrotliEncoderStreamState; + +typedef enum BrotliEncoderFlintState { + BROTLI_FLINT_NEEDS_2_BYTES = 2, + BROTLI_FLINT_NEEDS_1_BYTE = 1, + BROTLI_FLINT_WAITING_FOR_PROCESSING = 0, + BROTLI_FLINT_WAITING_FOR_FLUSHING = -1, + BROTLI_FLINT_DONE = -2 +} BrotliEncoderFlintState; + +typedef struct BrotliEncoderStateStruct { + BrotliEncoderParams params; + + MemoryManager memory_manager_; + + uint64_t input_pos_; + RingBuffer ringbuffer_; + size_t cmd_alloc_size_; + Command* commands_; + size_t num_commands_; + size_t num_literals_; + size_t last_insert_len_; + uint64_t last_flush_pos_; + uint64_t last_processed_pos_; + int dist_cache_[BROTLI_NUM_DISTANCE_SHORT_CODES]; + int saved_dist_cache_[4]; + uint16_t last_bytes_; + uint8_t last_bytes_bits_; + /* "Flint" is a tiny uncompressed block emitted before the continuation + block to unwire literal context from previous data. Despite being int8_t, + field is actually BrotliEncoderFlintState enum. */ + int8_t flint_; + uint8_t prev_byte_; + uint8_t prev_byte2_; + size_t storage_size_; + uint8_t* storage_; + + Hasher hasher_; + + /* Hash table for FAST_ONE_PASS_COMPRESSION_QUALITY mode. */ + int small_table_[1 << 10]; /* 4KiB */ + int* large_table_; /* Allocated only when needed */ + size_t large_table_size_; + + BrotliOnePassArena* one_pass_arena_; + BrotliTwoPassArena* two_pass_arena_; + + /* Command and literal buffers for FAST_TWO_PASS_COMPRESSION_QUALITY. */ + uint32_t* command_buf_; + uint8_t* literal_buf_; + + uint64_t total_in_; + uint8_t* next_out_; + size_t available_out_; + uint64_t total_out_; + /* Temporary buffer for padding flush bits or metadata block header / body. */ + union { + uint64_t u64[2]; + uint8_t u8[16]; + } tiny_buf_; + uint32_t remaining_metadata_bytes_; + BrotliEncoderStreamState stream_state_; + + BROTLI_BOOL is_last_block_emitted_; + BROTLI_BOOL is_initialized_; +} BrotliEncoderStateStruct; + +typedef struct BrotliEncoderStateStruct BrotliEncoderStateInternal; +#define BrotliEncoderState BrotliEncoderStateInternal + +#endif // BROTLI_ENC_STATE_H_ diff --git a/packages/runtime/vendor/brotli/c/enc/static_dict.c b/packages/runtime/vendor/brotli/c/enc/static_dict.c new file mode 100644 index 000000000..854674600 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/static_dict.c @@ -0,0 +1,536 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "static_dict.h" + +#include "../common/dictionary.h" +#include "../common/platform.h" +#include "../common/transform.h" +#include "encoder_dict.h" +#include "find_match_length.h" +#include "hash_base.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static BROTLI_INLINE void AddMatch(size_t distance, size_t len, size_t len_code, + uint32_t* matches) { + uint32_t match = (uint32_t)((distance << 5) + len_code); + matches[len] = BROTLI_MIN(uint32_t, matches[len], match); +} + +static BROTLI_INLINE size_t DictMatchLength(const BrotliDictionary* dictionary, + const uint8_t* data, + size_t id, + size_t len, + size_t maxlen) { + const size_t offset = dictionary->offsets_by_length[len] + len * id; + return FindMatchLengthWithLimit(&dictionary->data[offset], data, + BROTLI_MIN(size_t, len, maxlen)); +} + +static BROTLI_INLINE BROTLI_BOOL IsMatch(const BrotliDictionary* dictionary, + DictWord w, const uint8_t* data, size_t max_length) { + if (w.len > max_length) { + return BROTLI_FALSE; + } else { + const size_t offset = dictionary->offsets_by_length[w.len] + + (size_t)w.len * (size_t)w.idx; + const uint8_t* dict = &dictionary->data[offset]; + if (w.transform == 0) { + /* Match against base dictionary word. */ + return + TO_BROTLI_BOOL(FindMatchLengthWithLimit(dict, data, w.len) == w.len); + } else if (w.transform == 10) { + /* Match against uppercase first transform. + Note that there are only ASCII uppercase words in the lookup table. */ + return TO_BROTLI_BOOL(dict[0] >= 'a' && dict[0] <= 'z' && + (dict[0] ^ 32) == data[0] && + FindMatchLengthWithLimit(&dict[1], &data[1], w.len - 1u) == + w.len - 1u); + } else { + /* Match against uppercase all transform. + Note that there are only ASCII uppercase words in the lookup table. */ + size_t i; + for (i = 0; i < w.len; ++i) { + if (dict[i] >= 'a' && dict[i] <= 'z') { + if ((dict[i] ^ 32) != data[i]) return BROTLI_FALSE; + } else { + if (dict[i] != data[i]) return BROTLI_FALSE; + } + } + return BROTLI_TRUE; + } + } +} + +/* Finds matches for a single static dictionary */ +static BROTLI_BOOL BrotliFindAllStaticDictionaryMatchesFor( + const BrotliEncoderDictionary* dictionary, const uint8_t* data, + size_t min_length, size_t max_length, uint32_t* matches) { + BROTLI_BOOL has_found_match = BROTLI_FALSE; +#if defined(BROTLI_EXPERIMENTAL) + if (dictionary->has_words_heavy) { + const BrotliTrieNode* node = &dictionary->trie.root; + size_t l = 0; + while (node && l < max_length) { + uint8_t c; + if (l >= min_length && node->len_) { + AddMatch(node->idx_, l, node->len_, matches); + has_found_match = BROTLI_TRUE; + } + c = data[l++]; + node = BrotliTrieSub(&dictionary->trie, node, c); + } + return has_found_match; + } +#endif /* BROTLI_EXPERIMENTAL */ + { + size_t offset = dictionary->buckets[Hash15(data)]; + BROTLI_BOOL end = !offset; + while (!end) { + DictWord w = dictionary->dict_words[offset++]; + const size_t l = w.len & 0x1F; + const size_t n = (size_t)1 << dictionary->words->size_bits_by_length[l]; + const size_t id = w.idx; + end = !!(w.len & 0x80); + w.len = (uint8_t)l; + if (w.transform == 0) { + const size_t matchlen = + DictMatchLength(dictionary->words, data, id, l, max_length); + const uint8_t* s; + size_t minlen; + size_t maxlen; + size_t len; + /* Transform "" + BROTLI_TRANSFORM_IDENTITY + "" */ + if (matchlen == l) { + AddMatch(id, l, l, matches); + has_found_match = BROTLI_TRUE; + } + /* Transforms "" + BROTLI_TRANSFORM_OMIT_LAST_1 + "" and + "" + BROTLI_TRANSFORM_OMIT_LAST_1 + "ing " */ + if (matchlen >= l - 1) { + AddMatch(id + 12 * n, l - 1, l, matches); + if (l + 2 < max_length && + data[l - 1] == 'i' && data[l] == 'n' && data[l + 1] == 'g' && + data[l + 2] == ' ') { + AddMatch(id + 49 * n, l + 3, l, matches); + } + has_found_match = BROTLI_TRUE; + } + /* Transform "" + BROTLI_TRANSFORM_OMIT_LAST_# + "" (# = 2 .. 9) */ + minlen = min_length; + if (l > 9) minlen = BROTLI_MAX(size_t, minlen, l - 9); + maxlen = BROTLI_MIN(size_t, matchlen, l - 2); + for (len = minlen; len <= maxlen; ++len) { + size_t cut = l - len; + size_t transform_id = (cut << 2) + + (size_t)((dictionary->cutoffTransforms >> (cut * 6)) & 0x3F); + AddMatch(id + transform_id * n, len, l, matches); + has_found_match = BROTLI_TRUE; + } + if (matchlen < l || l + 6 >= max_length) { + continue; + } + s = &data[l]; + /* Transforms "" + BROTLI_TRANSFORM_IDENTITY + */ + if (s[0] == ' ') { + AddMatch(id + n, l + 1, l, matches); + if (s[1] == 'a') { + if (s[2] == ' ') { + AddMatch(id + 28 * n, l + 3, l, matches); + } else if (s[2] == 's') { + if (s[3] == ' ') AddMatch(id + 46 * n, l + 4, l, matches); + } else if (s[2] == 't') { + if (s[3] == ' ') AddMatch(id + 60 * n, l + 4, l, matches); + } else if (s[2] == 'n') { + if (s[3] == 'd' && s[4] == ' ') { + AddMatch(id + 10 * n, l + 5, l, matches); + } + } + } else if (s[1] == 'b') { + if (s[2] == 'y' && s[3] == ' ') { + AddMatch(id + 38 * n, l + 4, l, matches); + } + } else if (s[1] == 'i') { + if (s[2] == 'n') { + if (s[3] == ' ') AddMatch(id + 16 * n, l + 4, l, matches); + } else if (s[2] == 's') { + if (s[3] == ' ') AddMatch(id + 47 * n, l + 4, l, matches); + } + } else if (s[1] == 'f') { + if (s[2] == 'o') { + if (s[3] == 'r' && s[4] == ' ') { + AddMatch(id + 25 * n, l + 5, l, matches); + } + } else if (s[2] == 'r') { + if (s[3] == 'o' && s[4] == 'm' && s[5] == ' ') { + AddMatch(id + 37 * n, l + 6, l, matches); + } + } + } else if (s[1] == 'o') { + if (s[2] == 'f') { + if (s[3] == ' ') AddMatch(id + 8 * n, l + 4, l, matches); + } else if (s[2] == 'n') { + if (s[3] == ' ') AddMatch(id + 45 * n, l + 4, l, matches); + } + } else if (s[1] == 'n') { + if (s[2] == 'o' && s[3] == 't' && s[4] == ' ') { + AddMatch(id + 80 * n, l + 5, l, matches); + } + } else if (s[1] == 't') { + if (s[2] == 'h') { + if (s[3] == 'e') { + if (s[4] == ' ') AddMatch(id + 5 * n, l + 5, l, matches); + } else if (s[3] == 'a') { + if (s[4] == 't' && s[5] == ' ') { + AddMatch(id + 29 * n, l + 6, l, matches); + } + } + } else if (s[2] == 'o') { + if (s[3] == ' ') AddMatch(id + 17 * n, l + 4, l, matches); + } + } else if (s[1] == 'w') { + if (s[2] == 'i' && s[3] == 't' && s[4] == 'h' && s[5] == ' ') { + AddMatch(id + 35 * n, l + 6, l, matches); + } + } + } else if (s[0] == '"') { + AddMatch(id + 19 * n, l + 1, l, matches); + if (s[1] == '>') { + AddMatch(id + 21 * n, l + 2, l, matches); + } + } else if (s[0] == '.') { + AddMatch(id + 20 * n, l + 1, l, matches); + if (s[1] == ' ') { + AddMatch(id + 31 * n, l + 2, l, matches); + if (s[2] == 'T' && s[3] == 'h') { + if (s[4] == 'e') { + if (s[5] == ' ') AddMatch(id + 43 * n, l + 6, l, matches); + } else if (s[4] == 'i') { + if (s[5] == 's' && s[6] == ' ') { + AddMatch(id + 75 * n, l + 7, l, matches); + } + } + } + } + } else if (s[0] == ',') { + AddMatch(id + 76 * n, l + 1, l, matches); + if (s[1] == ' ') { + AddMatch(id + 14 * n, l + 2, l, matches); + } + } else if (s[0] == '\n') { + AddMatch(id + 22 * n, l + 1, l, matches); + if (s[1] == '\t') { + AddMatch(id + 50 * n, l + 2, l, matches); + } + } else if (s[0] == ']') { + AddMatch(id + 24 * n, l + 1, l, matches); + } else if (s[0] == '\'') { + AddMatch(id + 36 * n, l + 1, l, matches); + } else if (s[0] == ':') { + AddMatch(id + 51 * n, l + 1, l, matches); + } else if (s[0] == '(') { + AddMatch(id + 57 * n, l + 1, l, matches); + } else if (s[0] == '=') { + if (s[1] == '"') { + AddMatch(id + 70 * n, l + 2, l, matches); + } else if (s[1] == '\'') { + AddMatch(id + 86 * n, l + 2, l, matches); + } + } else if (s[0] == 'a') { + if (s[1] == 'l' && s[2] == ' ') { + AddMatch(id + 84 * n, l + 3, l, matches); + } + } else if (s[0] == 'e') { + if (s[1] == 'd') { + if (s[2] == ' ') AddMatch(id + 53 * n, l + 3, l, matches); + } else if (s[1] == 'r') { + if (s[2] == ' ') AddMatch(id + 82 * n, l + 3, l, matches); + } else if (s[1] == 's') { + if (s[2] == 't' && s[3] == ' ') { + AddMatch(id + 95 * n, l + 4, l, matches); + } + } + } else if (s[0] == 'f') { + if (s[1] == 'u' && s[2] == 'l' && s[3] == ' ') { + AddMatch(id + 90 * n, l + 4, l, matches); + } + } else if (s[0] == 'i') { + if (s[1] == 'v') { + if (s[2] == 'e' && s[3] == ' ') { + AddMatch(id + 92 * n, l + 4, l, matches); + } + } else if (s[1] == 'z') { + if (s[2] == 'e' && s[3] == ' ') { + AddMatch(id + 100 * n, l + 4, l, matches); + } + } + } else if (s[0] == 'l') { + if (s[1] == 'e') { + if (s[2] == 's' && s[3] == 's' && s[4] == ' ') { + AddMatch(id + 93 * n, l + 5, l, matches); + } + } else if (s[1] == 'y') { + if (s[2] == ' ') AddMatch(id + 61 * n, l + 3, l, matches); + } + } else if (s[0] == 'o') { + if (s[1] == 'u' && s[2] == 's' && s[3] == ' ') { + AddMatch(id + 106 * n, l + 4, l, matches); + } + } + } else { + /* Set is_all_caps=0 for BROTLI_TRANSFORM_UPPERCASE_FIRST and + is_all_caps=1 otherwise (BROTLI_TRANSFORM_UPPERCASE_ALL) + transform. */ + const BROTLI_BOOL is_all_caps = + TO_BROTLI_BOOL(w.transform != BROTLI_TRANSFORM_UPPERCASE_FIRST); + const uint8_t* s; + if (!IsMatch(dictionary->words, w, data, max_length)) { + continue; + } + /* Transform "" + kUppercase{First,All} + "" */ + AddMatch(id + (is_all_caps ? 44 : 9) * n, l, l, matches); + has_found_match = BROTLI_TRUE; + if (l + 1 >= max_length) { + continue; + } + /* Transforms "" + kUppercase{First,All} + */ + s = &data[l]; + if (s[0] == ' ') { + AddMatch(id + (is_all_caps ? 68 : 4) * n, l + 1, l, matches); + } else if (s[0] == '"') { + AddMatch(id + (is_all_caps ? 87 : 66) * n, l + 1, l, matches); + if (s[1] == '>') { + AddMatch(id + (is_all_caps ? 97 : 69) * n, l + 2, l, matches); + } + } else if (s[0] == '.') { + AddMatch(id + (is_all_caps ? 101 : 79) * n, l + 1, l, matches); + if (s[1] == ' ') { + AddMatch(id + (is_all_caps ? 114 : 88) * n, l + 2, l, matches); + } + } else if (s[0] == ',') { + AddMatch(id + (is_all_caps ? 112 : 99) * n, l + 1, l, matches); + if (s[1] == ' ') { + AddMatch(id + (is_all_caps ? 107 : 58) * n, l + 2, l, matches); + } + } else if (s[0] == '\'') { + AddMatch(id + (is_all_caps ? 94 : 74) * n, l + 1, l, matches); + } else if (s[0] == '(') { + AddMatch(id + (is_all_caps ? 113 : 78) * n, l + 1, l, matches); + } else if (s[0] == '=') { + if (s[1] == '"') { + AddMatch(id + (is_all_caps ? 105 : 104) * n, l + 2, l, matches); + } else if (s[1] == '\'') { + AddMatch(id + (is_all_caps ? 116 : 108) * n, l + 2, l, matches); + } + } + } + } + } + /* Transforms with prefixes " " and "." */ + if (max_length >= 5 && (data[0] == ' ' || data[0] == '.')) { + BROTLI_BOOL is_space = TO_BROTLI_BOOL(data[0] == ' '); + size_t offset = dictionary->buckets[Hash15(&data[1])]; + BROTLI_BOOL end = !offset; + while (!end) { + DictWord w = dictionary->dict_words[offset++]; + const size_t l = w.len & 0x1F; + const size_t n = (size_t)1 << dictionary->words->size_bits_by_length[l]; + const size_t id = w.idx; + end = !!(w.len & 0x80); + w.len = (uint8_t)l; + if (w.transform == 0) { + const uint8_t* s; + if (!IsMatch(dictionary->words, w, &data[1], max_length - 1)) { + continue; + } + /* Transforms " " + BROTLI_TRANSFORM_IDENTITY + "" and + "." + BROTLI_TRANSFORM_IDENTITY + "" */ + AddMatch(id + (is_space ? 6 : 32) * n, l + 1, l, matches); + has_found_match = BROTLI_TRUE; + if (l + 2 >= max_length) { + continue; + } + /* Transforms " " + BROTLI_TRANSFORM_IDENTITY + and + "." + BROTLI_TRANSFORM_IDENTITY + + */ + s = &data[l + 1]; + if (s[0] == ' ') { + AddMatch(id + (is_space ? 2 : 77) * n, l + 2, l, matches); + } else if (s[0] == '(') { + AddMatch(id + (is_space ? 89 : 67) * n, l + 2, l, matches); + } else if (is_space) { + if (s[0] == ',') { + AddMatch(id + 103 * n, l + 2, l, matches); + if (s[1] == ' ') { + AddMatch(id + 33 * n, l + 3, l, matches); + } + } else if (s[0] == '.') { + AddMatch(id + 71 * n, l + 2, l, matches); + if (s[1] == ' ') { + AddMatch(id + 52 * n, l + 3, l, matches); + } + } else if (s[0] == '=') { + if (s[1] == '"') { + AddMatch(id + 81 * n, l + 3, l, matches); + } else if (s[1] == '\'') { + AddMatch(id + 98 * n, l + 3, l, matches); + } + } + } + } else if (is_space) { + /* Set is_all_caps=0 for BROTLI_TRANSFORM_UPPERCASE_FIRST and + is_all_caps=1 otherwise (BROTLI_TRANSFORM_UPPERCASE_ALL) + transform. */ + const BROTLI_BOOL is_all_caps = + TO_BROTLI_BOOL(w.transform != BROTLI_TRANSFORM_UPPERCASE_FIRST); + const uint8_t* s; + if (!IsMatch(dictionary->words, w, &data[1], max_length - 1)) { + continue; + } + /* Transforms " " + kUppercase{First,All} + "" */ + AddMatch(id + (is_all_caps ? 85 : 30) * n, l + 1, l, matches); + has_found_match = BROTLI_TRUE; + if (l + 2 >= max_length) { + continue; + } + /* Transforms " " + kUppercase{First,All} + */ + s = &data[l + 1]; + if (s[0] == ' ') { + AddMatch(id + (is_all_caps ? 83 : 15) * n, l + 2, l, matches); + } else if (s[0] == ',') { + if (!is_all_caps) { + AddMatch(id + 109 * n, l + 2, l, matches); + } + if (s[1] == ' ') { + AddMatch(id + (is_all_caps ? 111 : 65) * n, l + 3, l, matches); + } + } else if (s[0] == '.') { + AddMatch(id + (is_all_caps ? 115 : 96) * n, l + 2, l, matches); + if (s[1] == ' ') { + AddMatch(id + (is_all_caps ? 117 : 91) * n, l + 3, l, matches); + } + } else if (s[0] == '=') { + if (s[1] == '"') { + AddMatch(id + (is_all_caps ? 110 : 118) * n, l + 3, l, matches); + } else if (s[1] == '\'') { + AddMatch(id + (is_all_caps ? 119 : 120) * n, l + 3, l, matches); + } + } + } + } + } + if (max_length >= 6) { + /* Transforms with prefixes "e ", "s ", ", " and "\xC2\xA0" */ + if ((data[1] == ' ' && + (data[0] == 'e' || data[0] == 's' || data[0] == ',')) || + (data[0] == 0xC2 && data[1] == 0xA0)) { + size_t offset = dictionary->buckets[Hash15(&data[2])]; + BROTLI_BOOL end = !offset; + while (!end) { + DictWord w = dictionary->dict_words[offset++]; + const size_t l = w.len & 0x1F; + const size_t n = (size_t)1 << dictionary->words->size_bits_by_length[l]; + const size_t id = w.idx; + end = !!(w.len & 0x80); + w.len = (uint8_t)l; + if (w.transform == 0 && + IsMatch(dictionary->words, w, &data[2], max_length - 2)) { + if (data[0] == 0xC2) { + AddMatch(id + 102 * n, l + 2, l, matches); + has_found_match = BROTLI_TRUE; + } else if (l + 2 < max_length && data[l + 2] == ' ') { + size_t t = data[0] == 'e' ? 18 : (data[0] == 's' ? 7 : 13); + AddMatch(id + t * n, l + 3, l, matches); + has_found_match = BROTLI_TRUE; + } + } + } + } + } + if (max_length >= 9) { + /* Transforms with prefixes " the " and ".com/" */ + if ((data[0] == ' ' && data[1] == 't' && data[2] == 'h' && + data[3] == 'e' && data[4] == ' ') || + (data[0] == '.' && data[1] == 'c' && data[2] == 'o' && + data[3] == 'm' && data[4] == '/')) { + size_t offset = dictionary->buckets[Hash15(&data[5])]; + BROTLI_BOOL end = !offset; + while (!end) { + DictWord w = dictionary->dict_words[offset++]; + const size_t l = w.len & 0x1F; + const size_t n = (size_t)1 << dictionary->words->size_bits_by_length[l]; + const size_t id = w.idx; + end = !!(w.len & 0x80); + w.len = (uint8_t)l; + if (w.transform == 0 && + IsMatch(dictionary->words, w, &data[5], max_length - 5)) { + AddMatch(id + (data[0] == ' ' ? 41 : 72) * n, l + 5, l, matches); + has_found_match = BROTLI_TRUE; + if (l + 5 < max_length) { + const uint8_t* s = &data[l + 5]; + if (data[0] == ' ') { + if (l + 8 < max_length && + s[0] == ' ' && s[1] == 'o' && s[2] == 'f' && s[3] == ' ') { + AddMatch(id + 62 * n, l + 9, l, matches); + if (l + 12 < max_length && + s[4] == 't' && s[5] == 'h' && s[6] == 'e' && s[7] == ' ') { + AddMatch(id + 73 * n, l + 13, l, matches); + } + } + } + } + } + } + } + } + return has_found_match; +} + +/* Finds matches for one or more dictionaries, if multiple are present + in the contextual dictionary */ +BROTLI_BOOL BrotliFindAllStaticDictionaryMatches( + const BrotliEncoderDictionary* dictionary, const uint8_t* data, + size_t min_length, size_t max_length, uint32_t* matches) { + BROTLI_BOOL has_found_match = + BrotliFindAllStaticDictionaryMatchesFor( + dictionary, data, min_length, max_length, matches); + + if (!!dictionary->parent && dictionary->parent->num_dictionaries > 1) { + uint32_t matches2[BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN + 1]; + int l; + const BrotliEncoderDictionary* dictionary2 = dictionary->parent->dict[0]; + if (dictionary2 == dictionary) { + dictionary2 = dictionary->parent->dict[1]; + } + + for (l = 0; l < BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN + 1; l++) { + matches2[l] = kInvalidMatch; + } + + has_found_match |= BrotliFindAllStaticDictionaryMatchesFor( + dictionary2, data, min_length, max_length, matches2); + + for (l = 0; l < BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN + 1; l++) { + if (matches2[l] != kInvalidMatch) { + uint32_t dist = (uint32_t)(matches2[l] >> 5); + uint32_t len_code = matches2[l] & 31; + uint32_t skipdist = (uint32_t)((uint32_t)(1 << dictionary->words-> + size_bits_by_length[len_code]) & ~1u) * + (uint32_t)dictionary->num_transforms; + /* TODO(lode): check for dist overflow */ + dist += skipdist; + AddMatch(dist, (size_t)l, len_code, matches); + } + } + } + return has_found_match; +} +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/static_dict.h b/packages/runtime/vendor/brotli/c/enc/static_dict.h new file mode 100644 index 000000000..bc69b1591 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/static_dict.h @@ -0,0 +1,39 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Class to model the static dictionary. */ + +#ifndef BROTLI_ENC_STATIC_DICT_H_ +#define BROTLI_ENC_STATIC_DICT_H_ + +#include "../common/platform.h" + +#include "encoder_dict.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN 37 +static const uint32_t kInvalidMatch = 0xFFFFFFF; + +/* Matches data against static dictionary words, and for each length l, + for which a match is found, updates matches[l] to be the minimum possible + (distance << 5) + len_code. + Returns 1 if matches have been found, otherwise 0. + Prerequisites: + matches array is at least BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN + 1 long + all elements are initialized to kInvalidMatch */ +BROTLI_INTERNAL BROTLI_BOOL BrotliFindAllStaticDictionaryMatches( + const BrotliEncoderDictionary* dictionary, + const uint8_t* data, size_t min_length, size_t max_length, + uint32_t* matches); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_STATIC_DICT_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/static_dict_lut.c b/packages/runtime/vendor/brotli/c/enc/static_dict_lut.c new file mode 100644 index 000000000..109366f60 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/static_dict_lut.c @@ -0,0 +1,224 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Lookup table for static dictionary and transforms. */ + +#include "static_dict_lut.h" + +#include "../common/platform.h" /* IWYU pragma: keep */ +#include "../common/static_init.h" + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +#include "../common/dictionary.h" +#include "../common/transform.h" +#include "hash_base.h" +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) + +/* TODO(eustas): deal with largest bucket(s). Not it contains 163 items. */ +static BROTLI_BOOL BROTLI_COLD DoBrotliEncoderInitStaticDictionaryLut( + const BrotliDictionary* dict, uint16_t* buckets, DictWord* words, + void* arena) { + DictWord* slots = (DictWord*)arena; + uint16_t* heads = (uint16_t*)(slots + BROTLI_ENC_STATIC_DICT_LUT_NUM_ITEMS); + uint16_t* counts = heads + BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS; + uint16_t* prev = counts + BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS; + size_t next_slot = 0; + uint8_t transformed_word[24]; + uint8_t transformed_other_word[24]; + size_t l; + size_t pos; + size_t i; + + memset(counts, 0, BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS * sizeof(uint16_t)); + memset(heads, 0, BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS * sizeof(uint16_t)); + memset(prev, 0, BROTLI_ENC_STATIC_DICT_LUT_NUM_ITEMS * sizeof(uint16_t)); + + for (l = 4; l <= 24; ++l) { + size_t n = 1u << dict->size_bits_by_length[l]; + const uint8_t* dict_words = dict->data + dict->offsets_by_length[l]; + for (i = 0; i < n; ++i) { + const uint8_t* dict_word = dict_words + l * i; + uint32_t key = Hash15(dict_word); + slots[next_slot].len = (uint8_t)l; + slots[next_slot].transform = BROTLI_TRANSFORM_IDENTITY; + slots[next_slot].idx = (uint16_t)i; + prev[next_slot] = heads[key]; + heads[key] = (uint16_t)next_slot; + counts[key]++; + ++next_slot; + } + for (i = 0; i < n; ++i) { + uint32_t key; + uint32_t prefix; + BROTLI_BOOL found; + size_t curr; + const uint8_t* dict_word = dict_words + l * i; + if (dict_word[0] < 'a' || dict_word[0] > 'z') continue; + memcpy(transformed_word, dict_word, l); + transformed_word[0] = transformed_word[0] - 32; + key = Hash15(transformed_word); + prefix = BROTLI_UNALIGNED_LOAD32LE(transformed_word) & ~0x20202020u; + found = BROTLI_FALSE; + curr = heads[key]; + while (curr != 0) { + const uint8_t* other_word; + uint32_t other_prefix; + if (slots[curr].len != l) break; + other_word = dict_words + l * slots[curr].idx; + other_prefix = BROTLI_UNALIGNED_LOAD32LE(other_word) & ~0x20202020u; + if (prefix == other_prefix) { + if (memcmp(transformed_word, other_word, l) == 0) { + found = BROTLI_TRUE; + break; + } + } + curr = prev[curr]; + } + if (found) continue; + slots[next_slot].len = (uint8_t)l; + slots[next_slot].transform = BROTLI_TRANSFORM_UPPERCASE_FIRST; + slots[next_slot].idx = (uint16_t)i; + prev[next_slot] = heads[key]; + heads[key] = (uint16_t)next_slot; + counts[key]++; + ++next_slot; + } + for (i = 0; i < n; ++i) { + const uint8_t* dict_word = dict_words + l * i; + BROTLI_BOOL is_ascii = BROTLI_TRUE; + BROTLI_BOOL has_lower = BROTLI_FALSE; + size_t k; + uint32_t prefix; + uint32_t key; + size_t curr; + BROTLI_BOOL found; + for (k = 0; k < l; ++k) { + if (dict_word[k] >= 128) is_ascii = BROTLI_FALSE; + if (k > 0 && dict_word[k] >= 'a' && dict_word[k] <= 'z') + has_lower = BROTLI_TRUE; + } + if (!is_ascii || !has_lower) continue; + memcpy(transformed_word, dict_word, l); + prefix = BROTLI_UNALIGNED_LOAD32LE(transformed_word) & ~0x20202020u; + for (k = 0; k < l; ++k) { + if (transformed_word[k] >= 'a' && transformed_word[k] <= 'z') { + transformed_word[k] = transformed_word[k] - 32; + } + } + key = Hash15(transformed_word); + found = BROTLI_FALSE; + curr = heads[key]; + while (curr != 0) { + const uint8_t* other_word; + uint32_t other_prefix; + if (slots[curr].len != l) break; + other_word = dict_words + l * slots[curr].idx; + other_prefix = BROTLI_UNALIGNED_LOAD32LE(other_word) & ~0x20202020u; + if (prefix == other_prefix) { + if (slots[curr].transform == BROTLI_TRANSFORM_IDENTITY) { + if (memcmp(transformed_word, other_word, l) == 0) { + found = BROTLI_TRUE; + break; + } + } else if (slots[curr].transform == + BROTLI_TRANSFORM_UPPERCASE_FIRST) { + if ((transformed_word[0] == (other_word[0] - 32)) && + memcmp(transformed_word + 1, other_word + 1, l - 1) == 0) { + found = BROTLI_TRUE; + break; + } + } else { + for (k = 0; k < l; ++k) { + if (other_word[k] >= 'a' && other_word[k] <= 'z') { + transformed_other_word[k] = other_word[k] - 32; + } else { + transformed_other_word[k] = other_word[k]; + } + } + if (memcmp(transformed_word, transformed_other_word, l) == 0) { + found = BROTLI_TRUE; + break; + } + } + } + curr = prev[curr]; + } + if (found) { + continue; + } + slots[next_slot].len = (uint8_t)l; + slots[next_slot].transform = BROTLI_TRANSFORM_UPPERCASE_ALL; + slots[next_slot].idx = (uint16_t)i; + prev[next_slot] = heads[key]; + heads[key] = (uint16_t)next_slot; + counts[key]++; + ++next_slot; + } + } + + if (next_slot != 31704) return BROTLI_FALSE; + pos = 0; + /* Unused; makes offsets start from 1. */ + words[pos].len = 0; + words[pos].transform = 0; + words[pos].idx = 0; + pos++; + for (i = 0; i < BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS; ++i) { + size_t num_words = counts[i]; + size_t curr; + if (num_words == 0) { + buckets[i] = 0; + continue; + } + buckets[i] = (uint16_t)pos; + curr = heads[i]; + pos += num_words; + for (size_t k = 0; k < num_words; ++k) { + words[pos - 1 - k] = slots[curr]; + curr = prev[curr]; + } + words[pos - 1].len |= 0x80; + } + return BROTLI_TRUE; +} + +BROTLI_BOOL BrotliEncoderInitStaticDictionaryLut( + const BrotliDictionary* dict, uint16_t* buckets, DictWord* words) { + size_t arena_size = + BROTLI_ENC_STATIC_DICT_LUT_NUM_ITEMS * + (sizeof(uint16_t) + sizeof(DictWord)) + + BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS * 2 * sizeof(uint16_t); + void* arena = malloc(arena_size); + BROTLI_BOOL ok; + if (arena == NULL) { + return BROTLI_FALSE; + } + ok = DoBrotliEncoderInitStaticDictionaryLut(dict, buckets, words, arena); + free(arena); + return ok; +} + +BROTLI_MODEL("small") +uint16_t kStaticDictionaryBuckets[BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS]; +BROTLI_MODEL("small") +DictWord kStaticDictionaryWords[BROTLI_ENC_STATIC_DICT_LUT_NUM_ITEMS]; + +#else /* BROTLI_STATIC_INIT */ + +/* Embed kStaticDictionaryBuckets and kStaticDictionaryWords. */ +#include "static_dict_lut_inc.h" + +#endif /* BROTLI_STATIC_INIT */ + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/static_dict_lut.h b/packages/runtime/vendor/brotli/c/enc/static_dict_lut.h new file mode 100644 index 000000000..078f55424 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/static_dict_lut.h @@ -0,0 +1,49 @@ +/* Copyright 2015 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Lookup table for static dictionary and transforms. */ + +#ifndef BROTLI_ENC_STATIC_DICT_LUT_H_ +#define BROTLI_ENC_STATIC_DICT_LUT_H_ + +#include "../common/dictionary.h" +#include "../common/platform.h" +#include "../common/static_init.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +typedef struct DictWord { + /* Highest bit is used to indicate end of bucket. */ + uint8_t len; + uint8_t transform; + uint16_t idx; +} DictWord; + +/* Buckets are Hash15 results. */ +#define BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS 32768 +#define BROTLI_ENC_STATIC_DICT_LUT_NUM_ITEMS 31705 + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +BROTLI_INTERNAL BROTLI_BOOL BrotliEncoderInitStaticDictionaryLut( + const BrotliDictionary* dictionary, uint16_t* buckets, DictWord* words); +BROTLI_INTERNAL extern BROTLI_MODEL("small") uint16_t + kStaticDictionaryBuckets[BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS]; +BROTLI_INTERNAL extern BROTLI_MODEL("small") DictWord + kStaticDictionaryWords[BROTLI_ENC_STATIC_DICT_LUT_NUM_ITEMS]; +#else +BROTLI_INTERNAL extern const BROTLI_MODEL("small") uint16_t + kStaticDictionaryBuckets[BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS]; +BROTLI_INTERNAL extern const BROTLI_MODEL("small") DictWord + kStaticDictionaryWords[BROTLI_ENC_STATIC_DICT_LUT_NUM_ITEMS]; +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_STATIC_DICT_LUT_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/static_dict_lut_inc.h b/packages/runtime/vendor/brotli/c/enc/static_dict_lut_inc.h new file mode 100644 index 000000000..fea97f8d7 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/static_dict_lut_inc.h @@ -0,0 +1,5830 @@ +const BROTLI_MODEL("small") +uint16_t kStaticDictionaryBuckets[BROTLI_ENC_STATIC_DICT_LUT_NUM_BUCKETS] = { +1,0,0,0,0,0,0,0,0,3,6,0,0,0,0,0,20,0,0,0,21,0,22,0,0,0,0,0,0,0,0,23,0,0,25,0,29, +0,53,0,0,0,0,0,0,55,0,0,0,0,0,0,61,76,0,0,0,94,0,0,0,0,0,0,96,0,97,0,98,0,0,0,0, +0,0,0,99,101,106,108,0,0,0,0,0,110,0,111,112,0,113,118,124,0,0,0,0,0,125,128,0,0 +,0,0,129,0,0,131,0,0,0,0,0,0,132,0,0,135,0,0,0,137,0,0,0,0,0,138,139,0,0,0,0,0,0 +,0,142,143,144,0,0,0,0,0,145,0,0,0,146,149,151,152,0,0,153,0,0,0,0,0,0,0,0,0,0,0 +,0,0,0,0,154,0,0,0,0,0,0,155,0,0,0,0,160,182,0,0,0,0,0,0,183,0,0,0,188,189,0,0, +192,0,0,0,0,0,0,194,0,0,0,0,0,0,0,0,197,202,209,0,0,210,0,224,0,0,0,225,0,0,0,0, +0,0,0,0,0,0,231,0,0,0,232,0,240,0,0,242,0,0,0,0,0,0,0,0,0,0,0,244,0,0,0,246,0,0, +249,251,253,0,0,0,0,0,258,0,0,261,263,0,0,0,267,0,0,268,0,269,0,0,0,0,0,0,0,0,0, +271,0,0,0,0,0,0,272,0,273,0,277,0,278,286,0,0,0,0,287,0,289,290,291,0,0,0,295,0, +0,296,297,0,0,0,0,0,0,0,0,0,0,298,0,0,0,299,0,0,305,0,324,0,0,0,0,0,327,0,328, +329,0,0,0,0,336,0,0,340,0,341,342,343,0,0,346,0,348,0,0,0,0,0,0,349,351,0,0,355, +0,363,0,364,0,368,369,0,370,0,0,0,0,0,0,0,372,0,0,0,0,0,0,0,0,0,0,0,373,0,375,0, +0,0,0,376,377,0,0,394,395,396,0,0,398,0,0,0,0,400,0,0,408,0,0,0,0,420,0,0,0,0,0, +0,421,0,0,422,423,0,0,429,435,436,442,0,0,443,0,444,445,453,456,0,457,0,0,0,0,0, +458,0,0,0,459,0,0,0,460,0,462,463,465,0,0,0,0,0,0,466,469,0,0,0,0,0,0,470,0,0,0, +474,0,476,0,0,0,0,483,0,485,0,0,0,486,0,0,488,491,492,0,0,497,499,500,0,501,0,0, +0,505,0,0,506,0,0,0,507,0,0,0,509,0,0,0,0,511,512,519,0,0,0,0,0,0,529,530,0,0,0, +534,0,0,0,0,543,0,0,0,0,0,0,0,0,0,553,0,0,0,0,557,560,0,0,0,0,0,0,561,0,564,0,0, +0,0,0,0,565,566,0,575,0,619,0,620,0,0,623,624,0,0,0,625,0,0,626,627,0,0,628,0,0, +0,0,630,0,631,0,0,0,0,0,0,0,0,0,641,0,0,0,0,643,656,668,0,0,0,673,0,0,0,674,0,0, +0,0,0,0,0,0,682,0,687,0,690,0,693,699,700,0,0,0,0,0,0,704,705,0,0,0,0,707,710,0, +711,0,0,0,0,726,0,0,729,0,0,0,730,731,0,0,0,0,0,752,0,0,0,762,0,763,0,0,767,0,0, +0,770,774,0,0,775,0,0,0,0,0,0,0,0,0,0,776,0,0,0,777,783,0,0,0,785,788,0,0,0,0, +790,0,0,0,793,0,0,0,0,794,0,0,804,819,821,0,827,0,0,0,834,0,0,835,0,0,0,841,0, +844,0,850,851,859,0,860,0,0,0,0,0,0,0,874,0,876,0,877,890,0,0,0,0,0,0,0,0,893, +894,898,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,899,0,0,0,900,904,906,0,0,0,907,0,908,909, +0,910,0,0,0,0,911,0,0,0,0,0,916,0,0,0,922,925,0,930,0,934,0,0,0,0,0,943,0,0,944, +0,953,954,0,0,0,0,0,0,955,0,962,963,0,0,976,0,0,977,978,979,980,0,981,0,0,0,0, +984,0,0,985,0,0,987,989,991,0,0,0,0,0,0,0,0,0,992,0,0,0,993,0,0,0,0,0,0,996,0,0, +0,1000,0,0,0,0,0,1002,0,0,0,0,1005,1007,0,0,0,1009,0,0,0,1010,0,0,0,0,0,0,1011,0 +,1012,0,0,0,0,1014,1016,0,0,0,1020,0,1021,0,0,0,0,1022,0,0,0,1024,0,0,0,0,0,0, +1025,0,0,1026,1027,0,0,0,0,0,1031,0,1033,0,0,0,0,1034,0,0,0,1037,1040,0,0,0,1042 +,1043,0,0,1053,0,1054,0,0,1057,0,0,0,1058,0,0,1060,0,0,0,0,0,0,0,1061,0,0,1062,0 +,0,0,0,1063,0,0,0,0,1064,0,0,0,0,0,1065,0,0,0,0,1066,1067,0,0,0,1069,1070,1072,0 +,0,0,0,0,0,1073,0,1075,0,0,0,0,0,0,1080,1084,0,0,0,0,1088,0,0,0,0,0,0,1094,0, +1095,0,1107,0,0,0,1112,1114,0,1119,0,1122,0,0,1126,0,1129,0,1130,0,0,0,0,0,1132, +0,0,0,0,0,0,1144,0,0,1145,1146,0,1148,1149,0,0,1150,1151,0,0,0,0,1152,0,1153,0,0 +,0,0,0,1154,0,1163,0,0,0,1164,0,0,0,0,0,1165,0,1167,0,1170,0,0,0,0,0,1171,1172,0 +,0,0,0,0,0,0,0,1173,1175,1177,0,1186,0,0,0,0,0,0,0,0,0,0,1195,0,0,1221,0,0,1224, +0,0,1227,0,0,0,0,0,1228,1229,0,0,1230,0,0,0,0,0,0,0,0,0,1231,0,0,0,1233,0,0,1243 +,1244,1246,1248,0,0,0,0,1254,1255,1258,1259,0,0,0,1260,0,0,1261,0,0,0,1262,1264, +0,0,1265,0,0,0,0,0,0,0,0,0,0,0,0,1266,0,1267,0,0,0,0,1273,1274,1276,1289,0,0, +1291,1292,1293,0,0,1294,1295,1296,0,0,0,0,1302,0,1304,0,0,0,0,0,0,0,0,0,1311, +1312,0,1314,0,1316,1320,1321,0,0,0,0,0,0,0,1322,1323,1324,0,1335,0,1336,0,0,0,0, +1341,1342,0,1346,0,1357,0,0,0,1358,1360,0,0,0,0,0,0,1361,0,0,0,1362,1365,0,1366, +0,0,0,0,0,0,0,1379,0,0,0,0,0,0,0,0,0,0,0,0,1386,0,1388,0,0,0,0,0,0,0,0,0,0,0,0,0 +,0,1395,0,0,0,0,1403,0,1405,0,0,1407,0,0,0,0,0,1408,1409,0,1410,0,0,0,1412,1413, +1416,0,0,1429,1451,0,0,1454,0,0,0,0,0,0,0,1455,0,0,0,0,0,0,0,1456,0,0,0,0,1459, +1460,1461,1475,0,0,0,0,0,0,1477,0,1480,0,1481,0,0,1486,0,0,1495,0,0,0,1496,0,0, +1498,1499,1501,1520,1521,0,0,0,1526,0,0,0,0,1528,1529,0,1533,1536,0,0,0,1537, +1538,1549,0,1550,1558,1559,1572,0,1573,0,0,0,0,0,0,0,0,0,1575,0,0,0,0,0,1579,0, +1599,0,1603,0,1604,0,1605,0,0,0,0,0,1608,1610,0,0,0,0,1611,0,1615,0,1616,1618,0, +1619,0,0,1622,0,0,0,0,1634,0,0,0,1635,0,0,0,1641,0,0,0,0,0,0,0,0,0,1643,0,0,0, +1650,0,0,1652,0,0,0,0,0,1653,0,0,0,1654,0,0,0,0,1655,0,1662,0,0,1663,1664,0,0, +1668,0,0,1669,1670,0,1672,1673,0,0,0,0,0,1674,0,0,0,1675,1676,1680,0,1682,0,0, +1687,0,0,0,0,0,1704,0,0,1705,0,0,1721,0,0,0,0,1734,1735,0,0,0,0,1737,0,0,0,0, +1739,0,0,1740,0,0,0,0,0,0,0,0,0,0,1741,1743,0,0,0,0,1745,0,0,0,1749,0,0,0,1751,0 +,0,0,0,0,0,1760,0,0,0,0,1765,0,0,0,0,0,1784,0,1785,1787,0,0,0,0,1788,1789,0,0,0, +0,1790,1791,1793,0,1798,1799,0,0,0,0,1801,0,1803,1805,0,0,0,1806,1811,0,1812, +1814,0,1821,0,0,0,0,0,1822,1833,0,0,0,0,0,0,1848,0,0,0,0,0,0,1857,0,0,0,1859,0,0 +,0,0,1861,0,0,0,0,0,0,0,1866,0,1921,1925,0,0,0,1929,1930,0,0,0,0,0,0,0,0,0,1931, +0,0,0,0,1932,0,0,0,1934,0,0,0,0,0,0,0,0,1946,0,0,1948,0,0,0,0,1950,0,1957,0,1958 +,0,0,0,0,0,1965,1967,0,0,0,0,1968,0,1969,0,1971,1972,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +,0,1973,0,0,0,0,1975,0,0,0,0,1976,1979,0,1982,0,0,0,0,1984,1988,0,0,0,0,1990, +2004,2008,0,0,0,2012,2013,0,0,0,0,0,0,0,0,0,0,2015,0,2016,2017,0,0,0,0,2021,0,0, +2025,0,0,0,0,0,2029,2036,2040,0,2042,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2043,0,0,0,0,0, +2045,0,0,0,0,0,0,0,2046,2047,0,2048,2049,0,2059,0,0,2063,0,2064,2065,0,0,2066,0, +0,0,0,0,0,2069,0,0,0,0,2070,0,2071,0,2072,0,0,0,0,2080,2082,2083,0,0,0,0,0,2085, +0,2086,2088,2089,2105,0,0,0,0,2107,0,0,2116,2117,0,2120,0,0,2122,0,0,0,0,0,2123, +0,0,2125,2127,2128,0,0,0,2130,0,0,0,2137,2139,2140,2141,0,0,0,0,0,0,0,0,0,2144, +2145,0,0,2146,2149,0,0,0,0,2150,0,0,2151,2158,0,2159,0,2160,0,0,0,0,0,0,2161, +2162,0,0,2194,2202,0,0,0,0,0,0,2205,2217,0,2220,0,2221,0,2222,2224,0,0,0,0,2237, +0,0,0,0,0,2238,0,2239,2241,0,0,2242,0,0,0,0,0,2243,0,0,0,0,0,0,2252,0,0,2253,0,0 +,0,2257,2258,0,0,0,2260,0,0,0,0,0,0,0,2262,0,2264,0,0,0,0,0,2269,2270,0,0,0,0,0, +0,0,0,0,2271,0,2273,0,0,0,0,2277,0,0,0,0,2278,0,0,0,0,2279,0,2280,0,2283,0,0,0,0 +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2287,0,0,0,0,0,0,0,2289,2290,0,0,0,0,2291,0,2292,0, +0,0,2293,2295,2296,0,0,0,0,0,0,0,2298,0,0,0,0,0,2303,0,2305,0,0,2306,0,2307,0,0, +0,0,0,0,0,0,0,0,0,0,2313,2314,2315,2316,0,0,2318,0,2319,0,2322,0,0,2323,0,2324,0 +,2326,0,0,0,0,0,0,0,2335,0,2336,2338,2339,0,2340,0,0,0,2355,0,2375,0,2382,2386,0 +,2387,0,0,2394,0,0,0,0,2395,0,2397,0,0,0,0,0,2398,0,0,0,0,0,0,0,2399,2402,2404, +2408,2411,0,0,0,2413,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2415,0,0,2416,2417,2419,0,2420, +0,0,0,0,0,2425,0,0,0,2426,0,0,0,0,0,0,0,0,0,0,0,0,2427,2428,0,2429,0,0,2430,2434 +,0,2436,0,0,0,0,0,0,2441,2442,0,2445,0,0,2446,2457,0,2459,0,0,2462,0,2464,0,2477 +,0,2478,2486,0,0,0,2491,0,0,2493,0,0,2494,0,2495,0,2513,2523,0,0,0,0,2524,0,0,0, +0,0,0,2528,2529,2530,0,0,2531,0,2533,0,0,2534,2535,0,2536,2537,0,2538,0,2539, +2540,0,0,0,2545,2546,0,0,0,0,0,0,0,2548,0,0,2549,0,2550,2555,0,0,0,0,0,2557,0, +2560,0,0,0,0,0,0,0,0,0,0,0,2561,0,2576,0,0,0,0,0,0,0,0,0,2577,2578,0,0,0,2579,0, +0,0,0,0,0,0,2580,0,0,0,0,2581,0,0,0,0,2583,0,2584,0,2588,2590,0,0,0,2591,0,0,0,0 +,2593,2594,0,2595,0,2601,2602,0,0,2603,0,2605,0,0,0,2606,2607,2611,0,2615,0,0,0, +2617,0,0,0,0,0,0,0,0,0,0,0,0,0,2619,0,0,2620,0,0,0,2621,0,2623,0,2625,0,0,2628, +2629,0,0,2635,2636,2637,0,0,2639,0,0,0,2642,0,0,0,0,2643,0,2644,0,2649,0,0,0,0,0 +,0,2655,2656,0,0,2657,0,0,0,0,0,2658,0,0,0,0,0,2659,0,0,0,0,2664,2685,0,2687,0, +2688,0,0,2689,0,0,2694,0,2695,0,0,2698,0,2701,2706,0,0,0,2707,0,2709,2710,2711,0 +,0,0,2720,2730,2735,0,0,0,0,2738,2740,0,0,0,0,2747,0,0,0,0,0,0,2748,0,0,2749,0,0 +,0,0,0,2750,0,0,2752,2754,0,0,0,0,0,2758,0,0,0,0,2762,0,0,0,0,2763,0,0,0,0,0,0,0 +,2764,2767,0,0,0,0,2768,0,0,2770,0,0,0,0,0,0,0,2771,0,0,0,0,0,0,0,0,0,2772,0,0,0 +,0,0,2773,2776,0,0,2783,0,0,2784,0,2789,0,2790,0,0,0,2792,0,0,0,0,0,0,0,0,0,0, +2793,2795,0,0,0,0,0,0,2796,0,0,0,0,0,0,2797,2799,0,0,0,0,2803,0,0,0,0,2806,0, +2807,2808,2817,2819,0,0,0,0,0,2821,0,0,0,0,2822,2823,0,0,0,0,0,0,0,2824,0,0,2828 +,0,2834,0,0,0,0,0,0,2836,0,2838,0,0,2839,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2841, +0,0,0,2842,0,0,0,0,0,2843,2844,0,0,0,0,2846,0,0,2847,0,2849,0,2853,0,0,0,0,0, +2857,0,0,0,0,2858,0,2859,0,0,2860,0,2862,2868,0,0,0,0,2875,0,2876,0,0,2877,2878, +2884,2889,2890,0,0,2891,0,0,2892,0,0,0,2906,2912,0,2913,0,0,0,0,0,0,0,0,2916,0, +2934,0,0,0,0,0,2935,0,0,0,0,2939,0,2940,0,0,0,0,0,0,0,2941,0,0,0,2946,0,2949,0,0 +,2950,2954,2955,0,0,0,2959,2961,0,0,2962,0,2963,0,0,0,0,0,0,2964,2965,2966,2967, +0,0,0,0,0,0,0,2969,0,0,0,0,0,2970,2975,0,2982,2983,2984,0,0,0,0,0,2989,0,0,2990, +0,0,0,0,0,0,0,2991,0,0,0,0,0,0,0,0,2998,0,3000,3001,0,0,3002,0,0,0,3003,0,0,3012 +,0,0,3022,0,0,3024,0,0,3025,3027,0,0,0,3030,0,0,0,0,3034,3035,0,0,3036,0,3039,0, +3049,0,0,3050,0,0,0,0,0,0,3051,0,3053,0,0,0,0,3057,0,3058,0,0,0,0,0,0,0,0,3063,0 +,0,3073,3074,3078,3079,0,3080,3086,0,0,0,0,0,0,0,0,3087,0,3092,0,3095,0,3099,0,0 +,0,3100,0,3101,3102,0,3122,0,0,0,3124,0,3125,0,0,0,0,0,0,3132,3134,0,0,3136,0,0, +0,0,0,0,0,3147,0,0,3149,0,0,0,0,0,3150,3151,3152,0,0,0,0,3158,0,0,3160,0,0,3161, +0,0,3162,0,3163,3166,3168,0,0,3169,3170,0,0,3171,0,0,0,0,0,0,0,3182,0,3184,0,0, +3188,0,0,3194,0,0,0,0,0,0,3204,0,0,0,0,3209,0,0,0,0,0,0,0,0,0,0,0,3216,3217,0,0, +0,0,0,0,0,3219,0,0,3220,3222,0,3223,0,0,0,0,3224,0,3225,3226,0,3228,3233,0,3239, +3241,3242,0,0,3251,3252,3253,3255,0,0,0,0,0,0,0,0,3260,0,0,3261,0,0,0,3267,0,0,0 +,0,0,0,0,0,3271,0,0,0,3278,0,3282,0,0,0,3284,0,0,0,3285,3286,0,0,0,0,0,0,0,3287, +3292,0,0,0,0,3294,3296,0,0,3299,3300,3301,0,3302,0,0,0,0,0,3304,3306,0,0,0,0,0,0 +,3308,0,0,0,0,0,0,0,0,0,3311,0,0,0,0,0,0,0,0,3312,3314,3315,0,3318,0,0,0,0,0,0,0 +,0,3319,0,0,0,0,0,3321,0,0,0,0,0,0,0,0,0,3322,0,0,3324,3325,0,0,3326,0,0,3328, +3329,3331,0,0,3335,0,0,3337,0,3338,0,0,0,0,3343,3347,0,0,0,3348,0,0,3351,0,0,0,0 +,0,0,3354,0,0,0,0,0,0,0,0,0,0,3355,0,0,3365,3366,3367,0,0,0,0,0,0,3368,3369,0, +3370,0,0,3373,0,0,3376,0,0,3377,0,3379,3387,0,0,0,0,0,3390,0,0,0,0,0,0,0,3402,0, +3403,3436,3437,3439,0,0,3441,0,0,0,3442,0,0,3449,0,0,0,3450,0,0,0,0,0,0,0,3451,0 +,0,3452,0,3453,3456,0,3457,0,0,3458,0,3459,0,0,0,0,0,0,0,0,0,3460,0,0,3469,3470, +0,0,3475,0,0,0,3480,3487,3489,0,3490,0,0,3491,3499,0,3500,0,0,3501,0,0,0,3502,0, +3514,0,0,0,3516,3517,0,0,0,3518,0,0,0,0,3520,3521,3522,0,0,3526,3530,0,0,0,0, +3531,0,0,0,0,3536,0,0,0,0,0,0,0,3539,3541,0,0,3542,3544,0,3547,3548,0,0,3550,0, +3553,0,0,0,0,0,0,0,3554,0,3555,0,3558,0,3559,0,0,0,0,0,0,0,0,3563,0,3581,0,0,0, +3599,0,0,0,3600,0,3601,0,3602,3603,0,0,3606,3608,0,3610,3611,0,0,0,0,0,0,0,0,0, +3612,3616,3619,0,0,0,0,0,0,0,0,0,0,0,0,0,3624,3628,0,3629,3634,3635,0,0,0,0,0,0, +3636,0,3637,0,0,3638,3651,0,0,0,0,0,0,3652,3653,0,0,0,0,3656,3657,0,0,0,0,0,3658 +,0,0,0,0,3659,0,3661,3663,3664,0,3665,0,3692,0,0,0,3694,3696,0,0,0,0,0,0,0,0,0,0 +,0,0,3698,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3700,0,0,3701,0,0,0,3708,3709,0,0,0,3711 +,3712,0,0,0,0,0,3723,0,3724,3725,0,0,3726,0,0,0,0,0,0,3728,3729,0,3734,3735,3737 +,0,0,0,3743,0,3745,0,0,3746,0,0,3747,3748,0,3757,0,3759,3766,3767,0,3768,0,0,0,0 +,3769,0,0,3771,0,3774,0,0,0,0,0,0,3775,0,0,0,0,0,0,3776,0,3777,3786,0,3788,3789, +0,0,0,0,0,0,0,0,0,3791,0,3811,0,0,0,0,0,3814,3815,3816,3820,0,0,0,0,0,0,0,3821,0 +,0,3825,0,0,0,0,3835,0,0,3848,3849,0,0,0,0,3850,3851,3853,0,0,0,0,3859,0,3860, +3862,0,0,0,0,0,3863,0,0,0,0,0,0,0,0,3873,0,3874,0,3875,3886,0,3887,0,0,0,0,3892, +3913,0,3914,0,0,0,3925,3931,0,0,0,0,3934,3941,3942,0,0,0,0,3943,0,0,0,3944,0,0,0 +,0,0,3945,0,3947,0,0,0,3956,3957,0,0,0,0,0,0,0,0,0,3958,0,3959,3965,0,0,0,0,3966 +,0,0,0,3967,0,0,0,3968,3974,0,0,0,0,0,3975,3977,3978,0,0,0,0,3980,0,3985,0,0,0,0 +,0,0,0,0,3986,4011,0,0,4017,0,0,0,0,0,0,0,0,0,0,0,4018,0,0,0,0,4019,0,4023,0,0,0 +,4027,4028,0,0,0,0,0,0,0,0,4031,4034,0,0,4035,4037,4039,4040,0,0,0,0,0,4059,0, +4060,4061,0,4062,4063,4066,0,0,4072,0,0,0,0,0,0,0,0,0,0,0,0,0,4088,0,0,0,0,0, +4091,0,0,0,0,4094,4095,0,0,4096,0,0,0,0,0,4098,4099,0,0,0,4101,0,4104,0,0,0,4105 +,4108,0,4113,0,0,4115,4116,0,4126,0,0,4127,0,0,0,0,0,0,0,4128,4132,4133,0,4134,0 +,0,0,4137,0,0,4141,0,0,0,0,4144,4146,4147,0,0,0,0,4148,0,0,4311,0,0,0,4314,4329, +0,4331,4332,0,4333,0,4334,0,0,0,4335,0,4336,0,0,0,4337,0,0,0,4342,4345,4346,4350 +,0,4351,4352,0,4354,4355,0,0,4364,0,0,0,0,4369,0,0,0,4373,0,4374,0,0,0,0,4377,0, +0,0,0,4378,0,0,0,4380,0,0,0,4381,4382,0,0,0,0,0,0,0,4384,0,0,0,0,4385,0,0,0,4386 +,0,0,0,4391,4398,0,0,0,0,4407,4409,0,0,0,0,4410,0,0,4411,0,4414,4415,4418,0,4427 +,4428,4430,0,4431,0,4448,0,0,0,0,0,4449,0,0,0,4451,4452,0,4453,4454,0,4456,0,0,0 +,0,0,0,0,4459,0,4463,0,0,0,0,0,4466,0,4467,0,4469,0,0,0,0,0,0,0,0,0,0,0,0,0,4470 +,4471,0,4473,0,0,4475,0,0,0,0,4477,4478,0,0,0,4479,4481,0,4482,0,4484,0,0,0,0,0, +0,0,4486,0,0,4488,0,0,4497,0,4508,0,0,4510,4511,0,4520,4523,0,4524,0,4525,0,4527 +,0,0,4528,0,0,0,0,4530,0,4531,0,0,4532,0,0,0,4533,0,0,0,0,0,4535,0,0,0,4536,0,0, +0,0,0,4541,4543,4544,4545,4547,0,4548,0,0,0,0,4550,4551,0,4553,0,0,0,0,4562,0,0, +4571,0,0,0,4574,0,0,0,4575,0,4576,0,4577,0,0,0,4581,0,0,0,0,0,4582,0,0,4586,0,0, +0,4588,0,0,4597,0,4598,0,0,0,0,4616,4617,0,4618,0,0,0,0,4619,0,4620,0,0,4621,0, +4624,0,0,0,0,0,4625,0,0,0,0,4657,0,4659,0,4667,0,0,0,4668,4670,0,4672,0,0,0,0,0, +4673,4676,0,0,0,0,4687,0,0,0,0,4697,0,0,0,0,4699,0,4701,0,0,0,0,4702,0,0,4706,0, +0,4713,0,0,0,4714,4715,4716,0,0,0,0,0,0,0,0,0,0,0,0,4717,0,0,4720,0,4721,4729, +4735,0,0,0,4737,0,0,0,4739,0,0,0,4740,0,0,0,4741,0,0,0,0,0,4742,0,4745,4746,4747 +,0,0,0,0,0,0,0,0,4748,0,0,0,4749,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4751, +4786,0,4787,0,4788,4796,0,0,4797,4798,0,4799,4806,4807,0,0,0,0,4809,4810,0,0,0,0 +,0,0,4811,0,0,0,0,0,4812,0,4813,0,0,4815,0,4821,4822,0,0,0,0,4823,0,0,0,0,0,0,0, +0,0,0,4824,0,0,0,0,4826,0,0,0,4828,0,4829,0,0,0,4843,0,0,4847,0,4853,4855,4858,0 +,0,0,0,0,4859,0,4864,0,0,4879,0,0,0,0,4880,0,0,0,0,4881,0,4882,0,0,0,0,0,0,0,0,0 +,4883,0,0,0,0,4884,0,0,0,0,0,4886,4887,4888,4894,4896,0,4902,0,0,4905,0,0,4915,0 +,0,0,0,0,0,0,4916,4917,4919,4921,0,0,0,0,0,4926,0,0,0,0,4927,0,0,0,0,0,0,0,0, +4929,0,4930,4931,0,4938,0,4952,0,4953,4957,4960,4964,0,0,0,0,0,0,0,5019,5020, +5022,0,0,0,0,0,5023,0,0,0,5024,0,0,0,5025,0,0,0,0,5028,0,0,0,0,5029,5030,5031,0, +5033,0,0,0,0,0,0,0,0,0,5034,5035,0,5036,0,0,5037,0,0,0,0,5038,0,0,5039,0,0,0, +5041,5042,0,0,0,0,5044,5049,5054,0,5055,0,5057,0,0,0,5060,0,0,0,0,0,5063,0,5064, +5065,0,5067,0,0,0,5068,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5076,0,0,0,0,0,0, +0,5077,0,0,5078,5080,0,0,5083,0,0,0,0,0,0,0,0,5085,0,0,0,0,0,0,5098,5099,5101, +5105,5107,0,5108,0,5109,0,0,0,0,0,0,0,5110,0,0,0,0,0,5117,5118,0,5121,0,5122,0,0 +,5130,0,0,0,5137,0,0,0,5148,0,0,0,0,0,0,0,5151,5154,0,0,0,5155,0,0,5156,5159, +5161,0,0,0,0,5162,0,0,0,0,5163,5164,0,5166,0,0,0,0,0,0,0,0,0,0,5167,0,0,0,5172,0 +,0,0,0,0,0,5178,5179,0,0,5190,0,0,5191,5192,5194,0,0,5198,5201,0,0,0,0,0,5203,0, +5206,5209,0,0,0,0,0,0,5213,0,5214,5216,0,0,0,0,0,5217,0,0,0,0,0,0,0,0,5218,5219, +0,5231,0,0,5244,5249,0,5254,0,5255,0,0,5257,0,0,0,0,0,5258,0,5260,5270,0,5277,0, +0,0,0,0,0,5280,5281,5282,5283,0,0,0,0,0,5284,0,5285,0,0,0,0,0,5287,5288,0,0,0,0, +0,0,0,0,0,0,5289,5291,0,0,5294,0,0,5295,0,0,0,0,0,0,0,5304,0,0,5306,5307,5308,0, +5309,0,0,5310,0,0,0,0,5311,5312,0,5313,0,0,0,0,0,5316,0,0,0,5317,0,0,0,0,0,0,0,0 +,0,5325,0,0,0,0,0,0,5326,0,5327,5329,0,5332,0,0,0,0,5338,0,0,0,0,0,0,0,0,5340,0, +0,5341,0,0,0,5342,0,5343,5344,0,0,5345,0,0,0,0,0,0,5347,5348,0,0,0,0,0,0,0,0,0, +5349,0,5350,0,5354,0,0,0,0,5358,0,0,5359,0,0,5361,0,0,5365,0,5367,0,5373,0,0,0, +5379,0,0,0,5380,0,0,0,5382,0,5384,0,0,0,0,0,0,5385,0,0,0,0,5387,0,0,0,0,0,0,5388 +,5390,5393,0,0,0,0,0,0,0,0,0,0,0,5396,0,0,0,0,5397,5402,0,0,0,0,0,5403,0,0,0, +5404,5405,0,0,0,0,0,0,0,0,0,0,0,0,5406,0,0,0,0,5410,0,0,5411,0,5415,0,0,0,0,5416 +,5434,0,0,0,0,0,0,0,0,0,0,0,5438,0,5440,0,0,0,0,0,0,5441,5442,0,0,0,5443,5444, +5447,0,0,5448,5449,5451,0,0,0,5456,5457,0,0,0,5459,0,0,0,5461,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,5464,0,5466,0,0,5467,0,5470,0,0,5473,0,0,5474,0,0,5476,0,0,0,0,0,0,0,0 +,0,0,0,5477,0,0,0,0,0,0,0,5484,0,0,5485,5486,0,0,0,0,0,5488,0,0,0,0,0,0,0,5489,0 +,0,0,0,0,5507,0,0,0,5510,0,5511,0,0,5512,0,0,0,5513,0,5515,0,0,5516,5517,0,5518, +0,0,5522,0,0,0,0,0,5534,5535,0,0,5536,0,5538,0,0,5543,0,5544,0,0,5545,0,5547,0, +5557,0,0,5558,0,5560,5567,0,0,0,0,5568,0,0,0,5571,5573,0,5574,0,5575,0,0,0,0, +5577,0,0,5598,0,0,0,0,0,0,0,0,0,5600,5609,0,0,0,0,5610,0,0,5612,0,5624,0,5625,0, +0,0,5629,0,5641,0,5642,5643,0,0,0,0,0,0,5651,0,0,0,5652,5653,0,5661,5662,5678,0, +5679,0,0,0,0,5685,5686,0,0,0,0,0,5690,5692,0,5703,0,0,0,0,0,5706,0,0,0,0,5707,0, +0,0,0,0,0,5708,0,0,5709,0,5710,0,0,0,5712,0,5733,0,5734,5735,0,0,5744,5751,0,0,0 +,0,0,0,0,0,0,0,0,0,5752,0,5754,0,0,0,0,0,0,5757,5758,0,5760,5761,0,0,0,0,5763, +5764,5765,0,5766,0,5767,5768,0,5770,0,0,0,0,5776,5780,0,0,0,0,5782,0,0,0,0,5784, +0,0,5788,0,0,0,0,0,0,0,0,0,0,0,5797,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5799,0,0,5801, +0,0,0,5811,0,0,0,0,0,0,5816,0,0,5827,0,0,0,0,0,0,0,0,5830,5831,0,0,5832,0,0,5833 +,0,5835,5844,5845,0,5846,0,0,0,0,0,5850,0,0,0,0,0,5852,0,5855,5857,0,0,5859,0, +5861,0,0,5863,0,5865,0,0,0,5873,5875,0,0,0,5877,0,5879,0,0,0,5888,0,0,5889,5891, +0,5894,0,0,0,0,0,0,5895,0,5897,0,0,0,0,0,0,5907,0,5911,0,0,5912,0,5913,5922,5924 +,0,5927,5928,0,0,0,0,5929,5930,0,5933,0,0,0,0,5949,0,0,5951,0,0,0,0,0,0,0,0,5953 +,0,0,5954,0,5959,5960,5961,0,5964,0,0,0,5976,5978,5987,5990,0,0,0,0,0,5991,0, +5992,0,0,0,5994,5995,0,0,5996,0,0,6001,6003,0,0,0,0,6007,0,0,0,0,0,6008,0,0,6009 +,0,6010,0,0,0,6011,6015,0,6017,0,6019,0,6023,0,0,0,0,0,0,0,6025,0,0,0,0,0,0,0,0, +0,0,6026,0,6030,0,0,6032,0,0,0,6033,6038,6040,0,0,0,6041,6045,0,0,6046,0,0,6053, +0,0,6054,0,6055,0,0,0,0,0,0,6057,0,6063,0,0,0,6064,0,6066,6071,6072,0,0,0,0,0,0, +6075,6076,0,0,6077,0,0,0,0,0,0,0,0,0,6078,6079,0,0,0,0,0,0,0,0,6080,0,6083,0,0,0 +,0,0,6084,0,0,6088,0,6089,0,0,6093,6105,0,0,6107,0,6110,0,0,0,6111,6125,6126,0,0 +,0,6129,0,0,0,0,6130,0,0,0,6131,6134,0,0,0,0,0,0,6142,0,0,0,0,0,6144,0,0,6146, +6151,6153,0,6156,0,6163,0,6180,6181,0,0,0,0,0,6182,0,0,0,0,6184,6195,0,0,6206,0, +6208,0,0,6212,6213,6214,0,6215,0,0,0,6228,0,0,0,6234,0,0,0,0,0,0,6235,6240,0, +6242,6243,6244,0,6250,6255,0,0,0,0,0,6257,0,0,0,6258,6278,0,6284,0,0,0,6285,0,0, +0,0,0,0,0,0,6286,0,0,0,6320,0,0,6322,6332,0,0,0,0,0,0,0,0,6334,0,0,0,0,0,0,0, +6335,0,0,6337,0,6338,0,6339,6340,0,0,6356,6357,6369,0,0,0,6370,6371,6372,0,6373, +0,0,0,0,0,6376,0,0,0,0,0,6382,6383,6384,0,0,0,0,6386,0,6389,6397,6400,6411,0, +6414,0,0,0,0,0,0,0,6415,6416,0,0,0,0,0,0,6417,0,0,0,0,6418,0,0,0,0,0,0,0,6420,0, +6421,6423,6425,0,6429,6430,0,6433,6438,0,0,0,0,0,0,0,0,0,0,6439,6440,0,0,6441,0, +0,6444,0,0,0,0,6446,0,0,0,0,6447,6448,0,0,6450,0,0,0,6454,0,0,6455,0,6461,0,0,0, +0,0,0,6462,0,0,6463,0,6464,0,6465,6467,0,0,0,6468,0,6479,6480,0,0,0,0,0,0,0,6481 +,0,0,6485,6487,0,0,0,0,0,0,6493,0,0,0,0,0,0,0,0,6494,6495,6496,0,0,0,0,0,6498,0, +0,0,6507,6508,0,0,0,0,0,0,0,0,0,0,6511,6512,0,0,0,0,6513,0,0,0,6514,0,0,0,0,0, +6516,0,0,6517,6518,0,0,0,6519,6520,6521,0,6523,0,0,0,0,6524,6528,0,6530,0,0,6532 +,0,6578,0,0,0,6583,0,6584,0,0,0,6587,0,0,0,6590,0,6591,0,0,0,0,0,6592,0,0,0,0, +6593,6594,0,0,0,0,0,6599,6600,0,0,6601,6602,6604,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +6608,0,0,0,0,0,0,0,0,6610,6611,0,6615,0,6616,6618,6620,0,6637,0,0,0,0,6639,0,0,0 +,0,6641,0,6642,0,0,0,6647,0,6660,6663,0,6664,0,6666,6669,0,6675,6676,6677,0,0,0, +0,0,0,0,0,0,6678,0,0,0,6679,0,6680,0,0,0,0,0,0,0,6693,0,0,0,0,0,0,0,0,0,6704, +6705,6706,0,0,6711,6713,0,0,0,0,0,6716,0,0,0,6717,0,6719,6724,0,0,0,0,0,0,0,0, +6725,6726,0,0,0,0,0,6728,6729,6735,0,6737,6742,0,0,6743,6750,0,6751,0,0,6752, +6753,0,0,0,0,0,0,6754,0,0,0,0,0,6756,0,0,0,0,0,0,6763,0,0,6764,6765,0,0,0,6770,0 +,0,0,6776,6780,0,6781,0,0,0,6783,0,6784,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +6785,0,0,0,6792,0,0,0,6793,0,0,6802,0,0,0,0,0,6803,0,0,0,6804,0,0,0,6812,0,0, +6823,0,6824,6839,0,0,0,0,6852,0,0,6854,0,6856,6857,0,0,0,0,0,0,0,0,0,6867,0,6868 +,6870,6872,0,0,0,6873,6874,0,0,0,0,0,6875,0,0,6877,0,0,0,0,0,0,0,6878,0,0,0,6879 +,0,6880,0,0,0,0,0,0,0,0,0,0,6887,0,6888,6891,6893,0,6895,0,0,0,0,0,0,0,0,6899,0, +0,0,0,6901,0,0,0,0,6910,0,6911,0,0,6912,0,0,6913,6914,0,0,0,6915,0,0,0,6916,6919 +,0,0,0,0,0,0,6924,0,6925,0,0,0,6926,6927,6928,0,6929,0,6930,0,0,6931,6935,0,6936 +,0,0,0,0,6939,6940,6941,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6942,6948,6949,0,0,0,0,0,0 +,0,6952,6954,6963,6965,6966,0,0,6967,6968,0,0,0,0,0,0,0,0,0,6969,0,0,6970,6979,0 +,0,6980,0,0,6983,0,0,0,0,0,6984,0,0,0,0,0,0,0,6988,6990,6992,0,0,0,0,0,0,0,6995, +0,0,0,7012,0,0,0,0,0,0,0,0,0,7019,0,0,0,0,0,0,0,0,7021,0,0,7022,7023,7028,0,7030 +,7033,0,0,0,0,0,0,7038,0,0,0,0,0,0,0,0,0,0,7039,0,0,0,0,0,7046,0,7047,0,0,0,0,0, +0,0,0,0,0,0,7048,7052,0,0,0,0,0,7054,0,7060,0,0,0,0,7061,0,7065,0,0,0,0,7067, +7069,0,7070,7071,7072,0,0,7078,0,7080,7081,0,7083,0,0,0,7084,7087,7088,0,0,7090, +0,7093,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7107,0,0,7108,0,0,0,0,0,0,0,0,7110,0,7114,0 +,0,0,0,0,0,0,7115,0,7116,0,0,0,0,0,7117,0,0,7118,0,0,7124,0,7125,0,0,7126,0,0,0, +0,7128,0,0,0,0,0,7129,0,7130,0,7132,7133,0,0,7134,0,0,7139,0,7148,7150,0,0,0,0, +7152,0,0,0,7153,7156,7157,0,0,0,0,0,7158,0,0,0,0,0,0,0,0,0,0,7163,7165,7169,0, +7171,0,0,0,0,0,0,0,0,0,7172,0,7173,7181,0,0,0,0,0,7182,7185,0,0,0,0,7187,0,7201, +7204,0,0,0,0,0,7206,7207,0,0,0,0,7211,7216,0,7218,0,0,0,0,7226,7228,7230,7232, +7233,7235,7237,0,0,0,0,7238,7241,0,7242,0,0,7247,0,0,0,7266,0,0,0,0,0,0,0,7289,0 +,0,7290,7291,0,0,7292,0,7297,0,0,0,0,0,0,0,0,0,0,7300,0,7301,0,0,0,0,0,0,0,0,0,0 +,0,0,7302,0,0,0,0,7305,0,0,0,0,7307,0,7308,0,7310,0,7335,0,0,0,0,0,0,0,7337,0, +7343,7347,0,0,0,0,0,7348,0,7349,7350,7352,7354,0,0,0,0,7357,0,7358,7366,0,7367, +7368,0,0,7373,0,0,0,7374,0,0,0,0,0,0,0,7376,0,0,0,7377,0,0,0,0,0,7378,0,7379, +7380,0,0,0,0,0,7383,0,0,7386,0,0,0,0,7398,0,0,0,7399,7400,0,7401,0,0,0,0,0,0,0, +7402,0,0,0,0,0,7405,0,0,0,0,0,7406,0,0,0,0,0,0,0,0,7421,7427,7429,0,0,0,7435,0,0 +,7436,0,0,0,7437,0,0,0,0,0,0,7438,7443,0,7446,0,7448,0,0,0,0,0,0,0,0,0,0,7456,0, +0,0,0,0,7457,0,0,7461,0,0,0,0,0,7462,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7463,7466,7472, +0,7476,0,0,7490,0,7491,0,0,7493,0,0,0,7498,7499,0,0,7508,0,0,0,0,0,7512,0,0,0, +7513,7514,7516,0,0,0,0,7518,0,0,7519,7521,7522,0,0,0,7526,0,0,7529,0,0,7531,0, +7536,0,7538,0,7539,0,0,7541,7542,7546,0,0,0,0,0,7547,0,7548,0,0,0,0,0,7550,0,0, +7552,7553,0,0,0,0,0,0,0,0,0,0,7554,7563,0,7573,0,0,0,0,0,0,7574,7576,0,7578,7581 +,7583,0,0,0,7584,0,7587,0,0,0,0,0,7589,0,0,0,7594,0,0,7595,0,0,7600,7602,7610,0, +0,0,0,0,7612,0,7613,7614,0,0,7615,0,0,7616,0,7620,0,7621,7622,0,7623,0,0,0,0, +7626,0,0,0,0,7627,7629,7631,0,0,7633,0,0,0,0,0,7639,0,7640,7642,0,0,7643,0,0,0,0 +,7644,0,0,0,0,0,0,0,7645,0,0,0,0,0,7661,7662,7663,7665,0,7666,0,7667,0,7684,7688 +,7690,0,7691,0,0,0,0,0,0,7692,0,0,7700,0,7707,0,7708,0,7709,0,7721,0,0,0,7722,0, +7724,0,0,0,0,0,0,7729,7731,0,7732,0,7733,7735,0,0,0,0,0,0,0,7739,0,0,7741,7745,0 +,7748,0,0,0,7751,0,0,0,7752,0,0,0,0,0,0,0,7753,0,0,7756,0,7757,0,7759,0,7760,0,0 +,0,0,7761,7768,0,0,7769,0,0,7770,0,0,7771,0,0,7772,0,0,7773,0,0,0,0,0,7778,7783, +0,0,0,0,0,7784,7785,0,7790,0,0,0,0,7792,0,7798,0,0,0,0,0,7799,0,7810,0,0,7813,0, +7814,0,7816,0,7818,7824,7825,7826,0,7828,7830,0,0,0,7840,0,7842,0,7843,0,0,0,0, +7844,0,0,0,0,0,0,0,7846,0,0,0,0,0,7856,7857,7858,7862,0,7865,0,0,7866,0,0,7913,0 +,0,0,0,7914,0,0,7915,7917,7918,7919,0,7920,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7921, +7922,0,7924,0,0,7925,0,0,7927,0,7930,7935,0,0,7937,0,0,0,0,0,0,7939,0,7940,0,0,0 +,0,0,7941,0,0,0,0,7945,0,0,0,0,7949,0,0,0,0,0,0,0,0,7950,0,7953,0,0,0,0,0,0,0, +7968,0,0,0,0,7969,7972,7992,0,7993,0,0,0,0,0,0,0,0,0,0,0,7994,0,0,0,0,8007,8008, +0,0,0,0,0,0,0,0,0,0,0,0,8010,0,0,0,8012,0,0,0,0,0,0,0,0,8018,0,8028,8029,0,0, +8030,0,0,8032,8033,0,0,8034,8036,0,0,0,0,0,0,0,0,0,0,8037,0,0,0,8043,8052,8059, +8060,0,0,8061,0,0,0,8062,0,8063,0,8064,0,8066,8068,0,0,0,8080,8081,0,8089,0,0,0, +0,0,8092,0,0,0,0,0,0,8093,8110,0,0,0,0,0,0,0,8111,0,0,0,0,0,8112,8115,0,8117,0,0 +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8120,8121,8122,8128,8129,8130,8131,0,0,8139,0,0, +8144,0,0,0,0,8145,8146,8153,0,0,0,0,0,0,0,0,8154,0,8157,8160,8162,0,8164,8165,0, +0,0,0,8166,8167,0,0,8179,0,0,0,8185,0,0,0,8186,0,0,8187,0,0,0,8188,0,0,0,0,0, +8204,0,0,0,0,8210,0,0,0,0,0,8213,0,8214,0,0,8215,0,0,0,0,0,0,8218,0,0,0,0,0,0,0, +0,0,8219,0,8221,0,0,8222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8225,0,0,0,8233,0,0, +8242,0,0,0,0,0,0,0,0,0,0,0,8247,0,8248,8252,0,8256,8257,0,0,8261,0,8264,8265,0,0 +,0,0,8267,0,0,0,8269,0,0,0,0,0,0,0,0,0,8270,0,0,0,8278,0,8279,8283,0,0,8285,8286 +,8289,8292,0,0,0,0,8293,8295,8299,8300,8301,0,0,0,0,0,0,8304,8307,0,0,0,0,0,0,0, +8321,0,0,0,8322,8323,8325,8326,8327,0,0,8332,8338,0,0,8340,0,0,0,0,0,8350,0,0, +8351,0,8354,8355,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8360,8372,0,0,0,0,0,0,0,0,8377,0,0, +0,0,8380,0,0,0,8383,0,8384,0,0,0,0,8386,8392,0,0,8394,0,0,0,0,0,0,0,8396,8397,0, +8398,0,8399,0,0,0,0,0,8400,0,8401,8410,8411,0,8412,8413,8422,0,0,0,0,8423,0,0,0, +0,8424,0,0,8425,0,0,0,0,0,0,0,8441,8442,0,0,0,0,0,0,8443,0,0,8444,0,8447,0,0,0,0 +,8451,0,8458,0,8462,0,0,8468,0,8469,0,0,0,8470,0,8473,8479,8480,0,0,0,0,8481, +8483,0,0,0,0,0,0,0,0,0,8484,0,0,8490,0,0,0,0,0,0,8491,8493,8494,0,8528,0,0,0,0,0 +,0,0,8530,0,0,0,0,0,0,0,0,8534,8538,8540,0,0,8541,0,0,8545,0,8557,0,0,8569,8570, +0,0,8571,8574,8575,8579,0,8583,0,0,0,0,8591,0,0,0,0,0,0,0,0,8606,0,8607,0,0,0,0, +0,0,0,0,0,8608,0,0,8609,0,0,0,8610,0,0,0,8611,0,0,8613,8617,8621,0,0,8622,0,8623 +,0,8624,8625,0,0,0,0,0,0,0,0,0,8637,8638,8639,8650,0,0,0,0,8652,8654,8655,0,0,0, +0,0,0,0,0,0,0,8656,0,0,0,0,0,8657,0,0,0,0,0,0,0,0,0,8658,0,0,8659,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,8660,0,0,0,0,0,0,8661,8663,8664,0,0,0,0,8665,0,8669,0, +0,0,0,0,0,0,8671,8674,0,8684,0,8686,0,0,0,8689,0,0,0,8690,0,8706,0,0,0,0,0,0,0,0 +,0,0,0,8710,0,8711,8713,8714,8724,8727,8728,8733,8736,0,8737,8739,0,0,0,0,8742, +8743,8745,8754,0,0,0,0,8756,0,0,0,0,0,0,8757,8760,0,0,0,0,0,8762,8763,8764,0, +8766,8769,8770,8773,0,8774,0,8779,0,0,0,0,8780,0,0,8781,0,0,8783,0,0,0,0,0,0,0,0 +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8784,0,0,0,0,0,0,0,0,8785,0,0,0,0,8786,0,0,0,0,8788 +,8790,0,0,0,8803,0,8813,8814,0,0,0,0,0,8815,8816,0,0,0,0,8818,0,0,0,0,8822,8828, +8829,0,8831,0,0,0,0,8833,0,0,0,8834,0,0,0,8835,0,8836,0,0,0,8837,0,0,0,0,0,0, +8838,8839,0,0,0,0,0,0,0,0,0,0,0,8840,0,0,0,8841,0,8842,0,0,0,8846,0,0,0,0,0,0,0, +8847,0,8848,0,0,8864,0,0,8866,0,0,8870,8872,0,0,8873,8874,0,0,0,0,0,0,8875,0, +8876,0,0,0,0,8896,8900,0,0,0,0,8901,0,0,0,0,0,8904,0,8907,0,0,0,0,8911,8912,8913 +,0,0,0,8914,0,8915,0,0,0,0,0,0,0,0,0,0,0,0,8916,0,0,0,8929,0,0,0,0,0,0,0,0,0,0, +8930,0,8932,0,8943,0,0,0,8945,8947,0,0,0,0,8949,0,8950,0,8954,8957,0,0,8970,0,0, +0,0,8971,0,8996,0,0,0,0,8997,9000,0,0,0,0,9001,9002,0,9004,9009,9024,0,0,0,0,0,0 +,0,0,0,0,0,0,9027,9082,0,0,9083,9089,0,0,0,0,0,0,9090,0,0,0,9092,0,0,9093,0,9095 +,0,0,9096,9097,9101,9102,0,0,0,0,0,0,0,0,9112,0,0,0,0,0,0,9114,0,0,9120,0,9121, +9122,0,0,0,9123,9124,0,0,9125,0,0,9126,0,9127,0,0,9129,9131,0,0,0,9132,0,0,9136, +0,9144,0,0,9148,0,0,0,0,0,0,9149,0,9152,9163,0,0,9165,0,0,0,0,0,0,0,0,0,0,0,0,0, +9166,0,9169,0,0,0,0,0,0,0,9170,0,0,0,0,9172,0,9174,9175,9176,0,9177,0,0,0,0,0,0, +0,0,9186,0,9187,0,0,0,9188,9189,0,0,9190,0,0,0,0,9191,0,0,0,9193,0,0,0,0,9197, +9198,0,0,0,9208,9211,0,0,0,0,9216,9217,0,9220,0,0,0,0,9221,9222,9223,0,9224,9225 +,0,0,9227,0,9228,9229,0,0,9230,0,9232,0,9233,0,0,0,0,0,9234,9235,0,0,9237,0,0,0, +0,0,0,0,0,9238,9240,0,0,9241,0,0,0,0,9244,0,0,0,0,9247,0,0,0,0,0,0,0,0,0,0,9248, +0,0,0,9249,0,0,0,0,0,9250,0,0,0,0,9251,0,0,9252,9255,0,0,0,9256,0,0,0,0,0,0,0, +9257,0,0,9258,0,0,0,0,0,0,9259,0,0,0,0,0,9262,9263,0,0,9265,9266,0,0,0,0,0,0,0,0 +,9268,9271,0,0,0,0,0,0,0,0,0,9273,0,0,0,9276,9277,9279,0,0,0,0,0,0,0,9280,0,0, +9293,0,0,0,0,0,9297,9301,0,0,0,0,0,0,0,0,0,0,0,9308,9309,9313,9321,9322,0,9326, +9327,0,0,9477,0,9479,0,0,0,0,9482,0,0,0,9483,0,9484,0,0,0,0,0,0,0,0,0,9485,0,0, +9486,0,0,0,9489,0,0,0,0,9490,9491,0,0,0,0,9493,0,9495,9496,0,0,0,0,0,0,0,0,9500, +0,9502,0,0,0,0,0,9504,9507,0,9509,0,9511,0,0,9513,0,0,0,0,0,0,0,0,9515,0,0,0,0,0 +,0,9516,9517,0,0,0,0,9532,0,0,9533,0,0,9538,0,9539,9540,0,0,0,0,9541,0,0,0,9542, +0,0,0,0,0,0,0,0,9544,9545,0,9546,0,0,0,0,0,0,9547,9548,0,0,0,9550,0,9557,0,9558, +0,9561,0,9563,9570,0,9572,9574,9575,0,0,0,9577,9592,0,0,9596,0,0,0,9598,0,9600,0 +,9601,0,0,0,0,0,0,9608,0,9638,9639,0,0,0,0,0,0,0,9641,0,0,9643,9644,9645,9646,0, +0,0,9648,0,0,0,0,0,0,0,9650,9654,0,0,0,0,0,0,0,0,9655,0,0,0,0,0,9656,0,9657,0,0, +0,0,9658,0,0,9659,0,0,9664,0,0,9665,0,9667,9669,0,0,0,0,0,0,0,0,0,0,0,0,9671,0, +9673,9681,0,0,0,0,9682,9683,9684,0,0,0,0,9686,9698,0,0,9700,9701,9702,0,9703, +9717,0,0,0,0,9718,0,9726,0,0,0,0,9727,0,0,0,9728,0,9742,0,9744,0,0,0,9750,0,9754 +,9755,0,0,0,0,0,9756,0,9757,9768,0,9769,0,0,0,9770,9771,0,9773,0,9774,0,9775,0,0 +,0,9776,9777,9784,0,0,0,9786,0,9789,0,0,0,0,9793,9794,0,0,0,9808,0,0,0,0,0,9811, +0,0,0,0,0,0,0,0,0,0,0,0,9812,0,9820,0,9823,0,9828,0,0,0,0,9830,0,0,9833,9836,0,0 +,0,9840,0,0,0,9841,0,0,9842,0,9845,0,0,0,9847,9848,0,0,9855,0,0,0,0,0,0,9856, +9863,9865,0,0,0,0,0,0,0,0,9866,9867,9868,9873,9875,0,0,0,0,0,0,9880,0,9886,0,0,0 +,9887,0,0,9891,0,0,0,0,0,0,0,9906,9907,9908,0,0,0,9909,0,0,0,0,0,0,9910,0,0,0,0, +9913,0,0,0,0,9914,0,0,0,0,0,9922,0,0,0,0,9923,9925,0,0,0,0,0,0,9930,0,0,0,9931,0 +,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9932,0,9939,0,0,9940,9962,9966,0,9969,9970,0,0,9974 +,0,9979,9981,9982,0,0,0,9985,0,0,0,0,0,0,9987,0,0,0,0,0,0,0,9988,9993,0,0,9994,0 +,0,0,9997,0,10004,0,0,0,0,0,10007,10019,10020,10022,0,0,0,10031,0,0,0,0,0,10032, +0,0,10034,0,10036,0,0,0,0,10038,0,10039,10040,10041,10042,0,0,0,0,0,10043,0,0,0, +0,0,10045,10054,0,0,0,0,10055,0,0,10057,10058,0,0,0,0,0,0,10059,0,0,0,0,0,0,0, +10060,0,0,0,0,0,0,0,10063,0,10066,0,0,0,10070,0,10072,0,0,10076,10077,0,0,10084, +0,10087,10090,10091,0,0,0,10094,10097,0,0,0,0,0,0,10098,0,0,0,0,0,0,10103,0, +10104,0,10108,0,0,0,0,0,0,0,0,10120,0,0,0,10122,0,0,10125,0,0,0,0,10127,10128,0, +0,10134,0,10135,10136,0,10137,0,0,10147,0,10149,10150,0,0,10156,0,10158,10159, +10160,10168,0,0,10171,0,10173,0,0,0,10176,0,0,0,0,10177,0,0,0,0,10178,0,0,0,0, +10194,0,10202,0,0,10203,10204,0,10205,10206,0,10207,0,0,0,0,10209,0,0,0,0,0,0,0, +10213,0,0,0,0,0,0,10217,0,10229,0,10230,10231,0,0,10232,0,0,10237,10238,10244,0, +0,0,0,0,10250,0,10252,0,0,0,0,0,0,10255,0,0,10257,0,0,0,0,0,0,10258,0,10259,0,0, +0,0,0,0,0,0,10260,0,0,0,0,0,0,0,10284,10288,10289,0,0,0,10290,0,10296,0,0,0,0,0, +10297,0,0,0,0,0,0,10298,0,0,0,0,10299,10303,0,0,0,0,0,10306,0,0,0,10307,0,10308, +0,0,0,0,10311,0,0,0,0,0,0,0,10315,10317,0,0,0,10318,10319,0,10321,0,10326,0, +10328,0,0,0,0,10329,0,0,10331,0,10332,0,0,0,0,0,0,10334,0,0,10335,10338,0,0,0,0, +0,10339,10349,0,0,0,0,0,0,10351,0,10353,0,0,0,0,0,0,10362,0,10368,0,10369,0,0,0, +10372,10373,0,0,0,0,0,10374,0,0,0,10375,0,10376,0,0,10386,10388,10390,0,0,0,0,0, +0,0,10391,0,0,10392,10394,0,0,10396,0,10397,0,10403,0,0,0,0,0,0,0,0,10404,0, +10405,10410,0,0,10411,0,10412,0,0,0,0,0,0,0,10421,10422,10423,0,0,0,0,0,0,0,0,0, +10425,0,0,10427,0,0,10430,0,0,0,0,0,10432,0,10433,10434,0,0,0,0,10436,10437,0, +10438,0,10439,0,10444,10446,0,0,0,0,0,10448,0,0,0,0,0,10449,0,0,0,0,0,0,0,10451, +0,10453,0,0,0,10454,10457,0,0,10459,0,10469,0,0,0,0,0,10472,10481,0,0,0,0,0, +10482,10483,0,10492,0,0,0,0,0,0,0,0,0,0,10499,0,0,0,10502,0,0,10510,0,10521, +10524,0,0,10525,10526,10528,0,0,0,0,0,0,0,0,10530,0,0,0,0,10533,0,10534,0,0,0,0, +0,0,0,0,0,0,10535,10536,0,0,10544,0,10553,10556,0,10557,10559,0,0,0,0,0,10562, +10563,10564,0,10565,0,0,0,10566,0,10567,0,0,0,0,10575,0,0,10576,0,10578,0,0,0,0, +0,0,0,0,0,0,10585,10586,10587,10589,0,10590,0,0,10594,0,0,0,0,0,10598,0,0,10601, +0,0,0,10602,0,10603,0,10604,0,10605,0,0,10607,0,10626,0,10627,0,0,0,0,0,10629, +10630,10631,0,0,0,10646,0,0,0,10647,0,10650,0,10651,0,0,0,10652,10653,10655,0, +10658,0,0,10659,0,10667,0,0,0,0,10669,0,0,0,0,0,0,0,0,0,10670,0,0,0,10671,0,0,0, +0,10672,10673,0,10674,0,0,0,10676,0,0,0,0,0,0,10678,0,10682,0,0,10692,0,10697,0, +0,0,0,10698,0,0,0,10700,0,0,0,0,0,10703,0,10704,0,0,0,0,0,0,0,10705,0,10715, +10718,10720,0,0,10722,0,0,0,0,0,0,0,0,10723,0,0,0,0,10726,0,0,0,0,0,10727,10730, +10743,0,0,0,0,0,0,10744,0,0,10745,0,0,0,0,0,0,10748,0,0,0,0,10750,0,0,10752, +10753,0,0,0,10756,0,0,0,0,0,0,10758,0,0,0,10759,0,10769,0,0,10772,0,0,0,0,0,0, +10773,0,0,0,10777,0,0,10779,0,0,0,0,0,0,0,0,10780,10784,0,0,0,10789,0,0,0,10791, +0,0,0,0,0,0,0,0,0,10795,0,0,10796,0,10808,0,10809,0,0,0,10810,0,0,0,10812,0,0, +10814,0,0,0,0,0,0,0,0,0,10815,0,0,0,0,10816,10817,0,0,0,0,10819,0,10820,0,0,0,0, +10821,10822,10823,0,10826,10849,0,0,0,0,10850,0,0,10852,0,10853,0,0,10856,0,0, +10857,10858,10859,10860,0,0,0,0,0,0,10863,0,10866,10867,10872,10890,0,0,10891, +10892,0,0,0,0,0,10893,0,0,0,10896,10899,0,0,10900,10902,0,0,0,0,0,10903,0,0,0,0, +0,0,0,0,0,0,0,0,10905,0,10906,0,0,0,0,10908,10911,0,10912,0,0,10916,0,0,0,0,0, +10917,0,10918,0,0,0,10923,0,0,0,0,0,10924,0,0,10928,10929,0,0,10930,0,0,0,10932, +0,0,0,0,10939,0,0,10945,0,0,0,10947,0,0,10948,0,0,0,0,0,0,0,0,0,0,0,0,10958,0, +10960,10962,0,0,10964,0,0,0,10966,0,0,0,0,0,0,0,0,0,0,10967,0,0,0,10968,0,0,0, +10973,0,0,0,0,0,10975,0,0,0,10976,10978,0,0,10982,10984,10987,0,0,10988,0,10989, +0,0,10991,0,0,0,0,10992,0,0,0,10993,0,10995,0,0,0,10996,10997,0,0,0,10998,0, +10999,0,11001,0,0,0,0,0,0,11010,11012,0,11013,11016,11017,0,0,11019,11020,11021, +0,0,0,0,0,0,0,0,0,0,0,0,11022,0,0,11023,11029,0,0,0,0,11031,0,0,0,11034,0,0,0,0, +11055,0,0,0,0,0,11056,11060,0,0,0,0,0,0,11061,0,0,11064,11065,0,11066,0,11069,0, +11085,0,0,0,0,0,11086,0,0,0,11088,0,0,0,11094,0,0,0,11095,11096,0,0,0,0,0,0, +11097,11098,0,0,0,0,0,0,11099,0,0,11102,11108,0,0,0,11109,0,11114,11119,0,11131, +0,0,0,11142,0,0,11143,0,11146,0,11147,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11148,0, +11149,11152,11153,11154,0,11156,0,11157,0,0,0,11158,0,0,11159,11160,0,0,0,0,0,0, +0,0,0,0,0,0,11163,0,0,11164,11166,0,0,0,11172,11174,0,0,0,11176,0,0,0,0,0,11182, +11183,0,0,0,11184,11187,0,0,11188,11189,0,0,0,0,0,0,11194,0,0,0,0,0,0,0,11200, +11202,0,0,0,0,0,0,11203,0,11204,0,0,0,0,0,11205,0,0,0,11206,0,11207,0,0,11209,0, +11211,0,11214,0,0,11231,0,0,0,11293,11295,0,0,11296,11297,11302,0,0,0,11307,0,0, +0,0,11309,11310,0,11311,0,0,0,11313,0,11314,0,0,0,0,11334,0,11338,0,0,0,11339,0, +0,0,0,0,11340,0,11341,11342,0,11344,0,11345,0,0,0,11348,11349,0,0,11350,0,0,0, +11355,0,0,0,0,0,0,11356,0,11357,11370,0,0,11371,0,11374,11376,0,0,0,11377,0,0, +11378,11383,0,11386,11399,0,11400,11406,0,0,0,11408,0,0,11409,11412,0,0,0,0, +11417,0,0,0,11418,0,11421,0,11426,11429,0,0,0,0,0,11430,0,11437,0,11438,0,0,0,0, +0,11440,11453,0,0,0,0,0,0,11454,0,0,0,0,11455,0,0,11456,11460,11461,11463,0, +11469,0,11473,0,0,0,0,11474,0,0,0,11475,0,11476,11477,11480,0,0,0,0,11481,0,0, +11484,0,0,11487,0,0,0,0,0,0,0,0,0,0,11497,0,0,11502,0,11509,0,0,11510,11511, +11513,0,0,0,0,0,0,0,0,0,0,11515,0,0,0,0,11516,0,11520,11521,0,0,0,0,0,0,0,0,0,0, +0,11529,11530,11531,11534,0,0,11543,0,0,0,0,0,11547,0,11548,0,0,0,0,0,11552, +11556,0,11557,0,0,11559,0,11560,0,0,0,0,0,0,11561,0,0,11563,11564,0,11565,0,0,0, +0,11567,0,0,0,11569,0,11574,0,11575,0,0,0,11577,0,11578,0,0,0,11580,11581,0,0,0, +11582,11584,0,0,0,0,0,0,0,11587,0,11588,11591,0,11595,0,0,0,0,0,0,0,0,11596,0, +11597,0,0,0,0,11598,11601,0,0,0,11602,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11603, +11604,0,11606,0,0,11608,0,0,0,0,11610,0,0,11611,0,0,0,0,11613,0,11622,0,0,0, +11623,0,0,0,0,11625,0,0,11626,11627,11628,11630,0,0,0,0,0,0,11639,0,0,11646,0, +11648,11649,0,11650,0,0,0,0,0,0,0,0,0,11651,0,0,11652,11653,11656,0,0,11677, +11679,0,0,0,0,11680,0,0,11681,0,11685,0,0,0,0,0,0,0,0,11688,0,0,0,11716,0,11719, +0,0,0,0,0,11721,0,0,11724,11743,0,0,0,0,0,0,0,0,11745,11748,11750,0,0,0,0,0, +11751,0,0,0,11752,11754,0,11755,0,0,0,0,0,0,0,11759,0,0,0,0,0,0,11760,0,0,0, +11761,0,0,0,0,0,0,11766,11767,0,11772,11773,0,11774,0,0,11775,0,11777,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,11778,11780,0,0,0,0,0,0,0,11783,0,11784,0,0,0,11785, +0,0,0,11786,0,0,0,0,11788,0,0,11789,11791,11792,0,0,0,0,11795,11834,11835,11836, +0,0,11837,0,0,0,11838,0,0,11846,11851,0,11852,0,11869,0,0,0,11871,0,0,0,11872, +11874,0,0,0,0,0,0,11875,0,11876,11877,0,0,0,0,0,0,0,0,0,0,11883,0,0,0,0,0,0,0, +11884,0,11885,0,11886,0,0,11887,0,11894,11895,11897,11909,11910,0,11912,11918,0, +0,11920,0,11922,11924,11927,11928,0,0,0,0,11929,0,11934,0,0,0,0,0,11941,11943, +11944,0,11945,0,0,0,0,11948,11949,0,0,0,0,11953,0,11954,0,11955,0,11956,0,0,0,0, +0,11957,0,0,11959,0,0,0,0,0,0,0,0,11961,0,0,0,0,0,11978,0,0,0,11979,11980,11986, +11987,0,11992,0,0,0,0,0,11993,0,0,0,11994,0,11999,12004,12005,12006,0,0,0,0,0, +12011,0,0,12012,12014,0,0,12015,0,0,12019,12028,0,0,12029,0,0,12032,12033,0,0,0, +0,12034,0,12041,12043,0,0,12044,0,0,0,0,0,0,0,12046,0,0,0,0,0,0,0,12054,12055,0, +12056,0,0,0,12060,12064,0,0,0,0,0,12065,12067,12068,0,0,0,0,0,0,0,0,12074,0,0,0, +12075,12076,0,0,0,12079,0,12081,12086,12087,0,0,12088,0,0,0,0,12089,0,12092,0,0, +0,0,12097,0,0,0,0,0,0,0,0,12098,0,0,0,0,0,0,0,0,0,0,0,0,0,12102,12103,12104, +12111,0,0,12114,12116,0,0,0,12118,0,0,0,12119,12120,12128,0,0,0,0,12130,0,0,0,0, +0,0,12131,0,0,0,12132,12134,0,0,0,0,12137,0,12139,0,12141,0,0,12142,0,0,0,12144, +0,0,0,0,0,12145,0,12148,0,12153,0,0,0,0,12154,12171,12173,0,0,0,12175,0,0,0,0, +12178,0,0,0,0,0,0,0,12183,0,0,0,0,0,0,0,0,12184,0,0,0,12186,0,0,0,0,0,12187, +12188,0,0,12189,0,12196,0,12197,0,0,12198,0,12201,0,0,0,0,12203,0,12209,0,0,0,0, +12210,12211,12212,12213,0,12217,12218,0,0,0,0,0,0,0,0,0,12222,0,0,0,0,0,0,0, +12223,0,0,12229,0,0,0,0,12233,0,0,0,0,12234,0,0,12236,12242,0,0,0,12243,0,0,0, +12244,12253,0,12254,12256,0,12257,0,0,12275,0,0,0,0,0,12277,0,0,0,0,0,12278,0, +12289,0,0,12290,0,12292,12293,0,0,12294,0,12295,0,0,12296,0,12297,0,12298,0,0,0, +0,12301,0,0,0,0,0,0,0,0,0,0,0,0,0,12309,0,12338,12340,0,0,0,0,12341,0,0,0,0,0,0, +0,0,12342,12343,0,12344,0,0,0,0,0,0,0,0,0,12345,0,0,0,0,0,0,0,0,12346,0,0,0,0, +12348,0,0,0,0,0,0,0,0,0,0,0,0,12350,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12351,0,12355, +12356,12357,0,0,12367,12370,12371,0,0,0,0,0,12372,12376,0,0,0,0,0,0,0,0,12379,0, +12382,0,12383,0,0,12384,0,0,0,0,12393,0,0,12394,0,0,0,0,12398,12403,0,0,12404,0, +0,0,0,0,0,0,0,0,0,0,0,0,12410,0,0,0,12411,0,0,0,12412,0,0,0,0,12420,0,12421,0,0, +0,0,0,12423,0,12425,12429,0,0,0,12431,12432,0,0,0,0,0,0,0,0,0,0,0,0,12434,0,0,0, +0,0,12435,12436,0,0,0,0,0,0,0,0,12437,0,0,0,0,0,12438,0,0,0,0,0,0,0,0,12445,0,0, +0,12450,12451,0,0,0,0,0,0,0,0,12452,12475,0,0,12493,12494,0,0,0,12495,0,0,0,0, +12496,12502,12509,0,0,0,0,12510,0,12512,12513,0,0,0,0,12514,0,0,0,12515,0,12520, +0,0,0,12524,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12527,0,0,0,12528,0,0,0,12529,0,0,0, +0,0,12530,0,12535,0,0,12536,0,12538,0,0,0,0,0,0,0,0,0,0,0,0,12540,0,12548,0,0,0, +0,0,12550,0,0,0,12551,12552,0,0,0,12554,0,0,0,0,0,0,0,0,12555,0,0,12562,0,12565, +0,12566,0,0,0,0,0,0,0,0,0,0,0,0,12569,0,0,0,12571,12574,0,0,0,0,0,0,0,12577,0,0, +0,0,0,0,0,12578,12579,12603,0,12608,0,0,12611,0,12612,0,12615,0,12625,0,0,0,0, +12627,12646,0,12648,0,0,12657,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12670,0,0,12671,0, +12673,12677,0,0,0,0,0,0,0,0,0,0,0,12679,0,12681,0,12682,12693,0,12694,0,12697,0, +12701,0,0,0,12703,12704,0,0,0,0,12707,12737,0,0,12739,0,0,12740,0,0,12742,12743, +0,0,0,0,0,0,0,0,0,12745,0,12746,12747,0,12748,0,0,12759,12767,0,0,0,0,12773,0, +12774,12778,0,0,0,0,0,0,0,12779,0,0,0,0,0,12780,12793,0,12824,0,12825,0,12836,0, +0,0,0,12839,0,12842,0,0,0,0,0,0,0,0,0,0,0,0,12843,12845,0,12846,0,0,0,0,12847,0, +0,12850,12852,12853,0,0,0,12854,0,0,0,12855,0,12856,0,12858,0,0,12859,0,12862,0, +12863,0,0,12866,0,12869,12872,12873,0,0,0,0,0,0,0,0,0,12875,0,12877,0,0,12878,0, +0,0,0,0,0,0,0,0,12884,12885,12888,0,12889,0,0,0,0,12893,0,0,0,12895,12896,12898, +0,0,0,0,0,0,0,12902,0,12909,12910,0,12926,0,12928,0,0,0,12929,0,12930,0,0,0,0, +12931,0,12932,12933,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12934,0,12942,0,0,0,0,12944, +0,0,0,0,0,0,0,0,12946,0,0,12948,0,0,12949,0,0,0,0,12950,0,0,0,0,12951,0,12952,0, +12953,0,0,0,12954,12958,12959,0,0,0,0,0,12960,12964,0,0,0,0,0,12966,0,0,0,0,0,0, +0,0,12970,0,12971,0,0,0,0,0,0,12972,0,0,12982,0,0,0,12984,12985,0,12986,12996, +12997,13001,13002,0,0,0,0,13004,0,0,13005,0,0,13007,13009,0,13017,0,0,0,13020,0, +13021,0,0,0,0,0,0,0,0,0,0,13022,0,0,0,0,0,0,0,0,13024,13027,0,0,0,0,0,13028,0,0, +13029,0,0,0,0,0,0,0,13032,0,13037,0,0,0,0,0,0,13040,0,0,13041,0,0,0,13043,13044, +13046,0,0,0,0,13047,0,0,0,0,0,0,0,13049,13054,0,13056,0,0,13060,13061,0,0,0,0,0, +13067,0,0,13068,0,13071,0,0,0,0,0,13077,13078,0,0,0,0,0,13079,13080,13081,0, +13082,0,0,0,13085,0,0,0,0,0,0,0,13086,0,13087,13088,0,0,0,0,0,13094,0,13099,0, +13100,0,0,0,13101,0,13125,13126,13128,13129,0,0,13130,0,13131,0,0,0,0,0,0,13134, +0,0,0,0,0,0,0,0,0,0,0,13150,0,13168,0,0,0,0,0,0,0,0,0,13169,0,0,13170,0,0,0,0, +13174,0,0,0,13176,0,0,0,0,0,13177,0,13178,13183,13187,0,0,0,13189,0,0,13190,0,0, +13191,0,0,13206,0,0,0,13207,0,0,0,0,0,0,0,0,0,0,13212,0,0,13219,13232,0,0,0, +13241,0,13249,13253,0,0,0,0,0,13255,13259,0,13260,13261,0,13262,0,13272,0,0,0,0, +13276,0,0,0,0,13277,13299,0,0,13301,13302,0,0,13303,0,0,13305,0,13310,0,0,0, +13311,0,0,0,0,13325,0,13328,0,0,0,13329,0,0,0,0,0,0,13330,0,0,13331,0,13335,0,0, +13342,0,0,0,0,0,13343,0,13354,0,13362,0,13366,13367,13369,0,0,13371,13372,0, +13373,13374,0,13376,0,13380,13381,13386,0,13387,13388,0,13389,13391,13395,0,0,0, +0,0,13401,13409,0,13410,0,0,0,0,13420,0,0,0,0,0,13422,0,0,0,0,13423,0,0,0,0, +13425,0,0,0,0,0,13427,0,0,0,13428,0,0,13430,13438,0,13439,0,13445,0,13448,13449, +0,0,0,0,0,0,13451,0,13457,0,0,0,0,13458,13459,0,13460,0,0,0,0,13464,13465,13466, +13470,0,13471,13472,13474,13475,0,13476,0,0,13478,13479,0,13481,0,0,0,0,13487,0, +13490,0,13493,0,0,13494,0,0,13495,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13496,13497,0, +13500,0,0,13516,13522,0,0,13525,13528,0,0,0,13530,13535,0,13537,13539,0,13540,0, +13543,0,13544,0,0,0,0,0,0,13545,0,0,0,0,0,0,13547,0,0,0,13549,13555,0,0,0,13556, +13557,0,0,0,0,0,0,0,13558,0,13563,0,0,0,0,13564,0,0,0,0,0,0,0,0,13566,0,0,0,0,0, +0,13569,0,0,13571,0,0,0,0,13573,0,0,0,0,0,0,13578,0,0,0,0,0,0,0,0,0,0,13581,0, +13586,0,13595,0,13600,0,0,0,0,0,0,0,0,13601,13603,0,13604,13605,13606,13607,0,0, +13617,13618,0,0,0,0,0,0,0,13623,0,13625,13627,0,0,0,0,0,0,0,0,13629,0,0,0,13634, +0,0,0,13638,0,0,0,0,0,0,0,0,13654,0,0,0,0,0,0,0,0,0,0,13656,0,13659,0,0,13660,0, +0,13662,0,0,0,13663,0,13664,0,0,0,0,0,13668,0,13669,13671,0,0,13672,0,0,0,0,0,0, +13675,13685,0,13686,0,0,0,13687,0,0,0,13692,13694,13697,0,0,0,13702,0,0,0,0,0, +13705,0,0,0,0,13707,0,0,0,13714,0,0,0,0,0,0,0,0,0,13715,0,13716,13717,0,0,13719, +13724,13730,13731,0,0,0,0,0,0,0,0,13732,0,0,0,0,0,0,0,13734,0,13736,0,0,13737, +13738,13747,0,13751,0,0,13752,0,0,0,13753,0,13757,0,0,13762,13763,0,13764,13765, +0,13766,0,0,13767,0,0,0,13768,0,0,0,0,0,0,0,13769,0,0,13772,0,13775,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,13776,13778,13787,0,0,0,13797,0,13798,0,13801,0,13804, +13806,0,0,0,0,13816,13817,0,0,0,0,0,0,0,0,0,0,0,0,0,13834,0,13836,0,0,13838,0,0, +13839,0,13840,0,0,0,0,13842,0,0,0,0,0,0,13843,0,0,0,0,0,0,0,0,0,13845,0,0,0,0,0, +13858,0,0,13860,0,0,13861,0,0,13862,13863,0,13868,0,13869,13870,0,0,0,0,0,0,0,0, +0,0,13872,0,0,0,0,13873,13878,0,0,0,0,0,0,0,0,0,0,13886,0,13888,13889,13890,0,0, +13891,13894,0,13897,13899,13900,13904,0,0,13906,0,0,0,13909,0,0,0,13910,0,0,0, +13911,0,0,0,0,0,13912,13917,0,0,0,0,13918,0,13919,0,0,13920,0,0,0,13921,0,0, +13922,0,0,0,0,0,0,0,13924,0,13927,0,0,0,0,0,13932,0,13933,0,13934,0,0,13935,0, +13944,0,0,0,13954,0,0,13955,0,0,0,0,13956,0,13957,0,13967,13969,0,0,0,0,0,0,0,0, +0,0,0,0,13970,13990,0,13991,13994,0,13995,0,0,0,0,13996,0,0,13999,0,0,0,14018,0, +14019,0,14021,0,0,0,0,0,0,14041,0,0,0,0,0,0,0,0,14043,0,0,0,0,14046,0,0,0,14048, +14049,0,0,0,0,0,0,0,0,0,0,14051,0,0,14052,14056,0,14063,0,14064,14066,0,0,14067, +0,0,0,0,0,0,0,0,0,14068,0,0,0,14072,0,14074,14075,0,14076,14079,14085,14086, +14087,14093,0,0,0,0,14095,0,0,0,0,0,0,14096,14097,0,0,0,0,0,0,0,14098,0,14102,0, +0,0,0,0,14103,0,0,0,14104,0,0,14105,0,0,0,14107,14108,0,0,14109,0,0,0,0,0,0,0,0, +14117,0,0,0,0,14118,0,0,0,0,14119,0,0,14120,0,0,14121,0,14122,14127,0,14128, +14136,0,0,14138,0,14140,0,0,0,14141,14142,0,0,0,0,14146,0,0,14149,0,14151,0,0,0, +14152,0,0,14153,0,0,0,0,0,0,0,0,0,14154,0,14156,14157,0,0,14159,0,14161,0,0,0,0, +14162,0,0,0,0,0,0,14163,0,0,14173,0,0,0,0,0,0,14174,0,0,14176,0,0,14178,0,0, +14179,14181,0,0,14182,14185,14187,0,14190,0,0,14197,0,0,0,0,0,0,0,0,0,0,0,0, +14198,0,0,0,0,0,0,14199,14200,0,0,0,14204,0,0,14208,0,0,0,0,0,0,0,0,0,0,0,14231, +0,0,0,0,0,0,0,0,0,14234,0,0,14235,0,0,0,14240,14241,0,0,0,14246,0,0,0,14247,0, +14250,0,0,14251,0,0,14254,0,0,14256,0,0,0,14260,0,14261,0,0,0,0,14262,14267, +14269,0,0,14277,0,0,14278,0,14279,14282,0,0,0,14283,0,0,0,14284,14285,0,0,0,0, +14286,0,0,0,14288,0,0,0,14289,0,14290,0,14293,14301,14302,14304,14305,0,14307,0, +14308,14309,0,0,0,0,0,0,0,0,0,0,0,14311,14312,0,0,14317,0,0,0,0,0,0,0,14318,0,0, +0,0,14320,0,0,0,0,14321,14322,0,0,0,0,0,14326,14329,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +14330,14331,0,0,0,0,14332,0,0,0,14333,0,0,14337,14340,0,14341,0,0,14342,0,14345, +14346,0,0,14347,0,14362,0,0,0,0,0,14364,14365,14371,0,14373,0,0,14374,0,14379,0, +14400,0,0,0,0,0,14401,0,0,14405,0,14406,0,14408,14409,0,0,0,14417,0,0,14424,0,0, +0,0,0,0,0,0,0,14430,0,0,0,14431,0,0,14435,0,14440,0,0,0,0,0,0,14442,0,0,14443,0, +0,0,0,0,14446,0,0,0,0,0,0,0,14454,0,14457,0,14460,0,0,14466,0,0,0,0,0,14467,0,0, +0,0,0,0,14469,0,14477,0,0,0,0,0,0,14478,14482,0,0,0,14483,0,0,0,14485,14486,0,0, +0,14487,14488,14489,14492,14493,14494,14495,14496,14497,0,14499,0,14501,0,0,0,0, +0,0,0,0,0,0,14502,0,14507,14512,14513,14514,0,0,0,0,0,0,0,0,0,0,0,14515,14526, +14530,0,14537,0,14544,0,14547,0,0,14548,14550,14551,0,0,14552,0,0,0,14553,0, +14554,0,0,0,0,14556,14564,0,0,14565,14566,0,0,0,0,0,0,14568,0,0,14569,0,0,0, +14571,14576,0,0,14577,14578,14579,0,0,14580,0,0,0,0,14582,0,0,0,0,0,0,0,0,0,0,0, +0,14583,0,0,0,0,0,14587,0,14588,0,0,14600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,14601,0,0,14604,14605,14611,0,14613,0,0,0,0,14615,0,0,0,0,0,0,14627,0,14628,0, +0,0,0,14631,0,14633,14634,0,0,0,0,14635,0,0,0,0,0,0,0,0,14636,0,0,14639,14642,0, +0,0,0,14644,0,0,0,0,14645,14646,0,14653,0,0,14654,0,14658,0,14661,0,0,0,14665,0, +0,0,14668,0,0,0,0,0,0,0,0,0,14669,0,0,14670,0,0,0,14680,0,0,14681,0,0,0,0,0, +14682,14683,0,0,0,0,14686,0,0,0,0,14687,14697,0,0,0,0,14699,14705,14711,0,0,0,0, +0,0,0,0,0,0,14712,0,0,0,14713,0,0,0,0,14719,0,14720,14721,14726,0,0,0,14728, +14729,0,0,0,0,14731,0,0,0,0,0,0,0,14733,14736,14737,0,0,14740,14742,0,0,0,14744, +14753,0,0,0,0,14755,14758,14760,0,0,0,0,0,14761,14762,14765,14771,0,14772,0, +14773,14774,0,0,14775,0,0,14776,0,0,0,0,14777,0,14779,0,0,14782,0,0,14785,14786, +14788,0,0,0,0,0,14795,0,0,0,0,0,0,14798,0,14803,14804,14806,0,0,0,14809,0,0,0,0, +0,0,14810,0,0,0,0,14811,0,14812,0,0,0,0,0,14815,0,0,0,0,0,0,0,0,14816,0,14818,0, +0,0,0,0,0,14819,0,14820,0,14823,0,0,0,14824,0,0,14826,14827,0,0,0,0,0,0,0,0,0,0, +0,0,14830,0,0,0,0,0,14833,0,14845,0,0,0,0,0,14846,0,0,14847,14871,0,14873,0, +14876,0,14877,14878,14880,0,0,0,0,0,14881,0,14882,14894,0,0,0,0,14895,0,14907,0, +14908,0,0,0,0,0,0,0,14911,0,0,0,0,14920,0,0,14931,0,14932,14934,14935,0,0,14936, +0,14945,0,0,0,0,0,0,0,14947,0,0,14948,14949,14951,0,0,14952,0,0,0,14964,14973,0, +0,14990,0,0,0,0,14995,0,0,14998,15001,0,0,15002,15020,0,0,0,0,0,0,15021,0,15022, +0,0,0,0,15023,0,0,15025,15029,15033,0,0,0,15034,0,0,0,15035,0,0,0,0,0,15043, +15044,0,0,0,15045,15046,15048,15050,0,15065,0,0,0,0,15066,0,0,15075,15082,15084, +0,0,15085,15086,0,0,0,0,0,0,0,0,15088,0,0,0,15089,0,0,0,0,15094,0,15096,0,15097, +0,15100,0,0,15102,0,0,0,0,0,0,0,0,15105,0,0,15106,0,15109,15113,0,0,0,15115,0, +15118,0,0,0,0,0,0,15119,0,0,15120,0,0,0,0,0,15123,15129,0,0,0,15130,0,15131,0,0, +15134,0,15135,0,0,0,15137,15138,0,0,0,0,0,0,15139,0,0,0,0,0,15140,0,0,15154, +15162,0,15169,15170,0,15175,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15177,0,15178,15179,0, +0,0,0,0,15183,0,0,0,0,0,0,0,0,0,0,0,0,15185,15187,0,15194,15195,15196,0,0,0,0,0, +0,0,15204,0,0,0,0,15206,0,0,0,0,0,15207,0,0,0,0,0,0,0,0,0,15213,0,15214,0,0,0,0, +0,0,0,15232,0,0,0,0,15234,0,15238,15240,0,15248,0,0,0,0,15250,15251,0,0,0,0,0,0, +0,15252,0,0,0,15255,15262,15266,0,0,0,15267,0,0,0,15277,15279,0,0,0,15280,15281, +15282,0,0,0,0,0,15285,0,0,0,0,15289,0,0,15291,0,0,0,0,0,0,0,15296,15297,0,0, +15304,0,0,0,0,15306,0,0,0,0,0,0,15307,15308,0,15309,0,0,15311,0,0,15312,15313,0, +0,0,0,0,0,0,0,0,0,0,0,15314,15317,0,0,0,15318,15319,0,0,0,0,15320,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,15321,0,0,0,0,0,15324,0,15325,15326,0,15330,0,0,0,0,15334,0, +15335,0,15341,0,0,15342,0,0,15343,15344,0,0,0,0,15345,0,0,0,0,15347,0,0,15348, +15349,15350,0,15356,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15357,0,15358,0,0,0,0,0,0,0, +15359,15360,15364,0,15380,0,0,0,0,0,15392,0,0,15393,0,15395,0,0,0,0,0,0,0,0, +15396,0,0,15397,15398,0,0,0,0,0,0,0,0,0,15399,0,15400,0,0,0,15402,0,15405,15410, +0,0,0,0,15411,0,0,0,15412,0,15416,0,0,0,0,0,0,0,15428,0,15435,0,0,15438,0,0,0,0, +15439,0,0,0,15440,0,0,0,15441,15449,15451,0,0,0,0,0,0,0,15452,0,0,15455,0,0,0, +15456,0,0,15458,0,15460,15461,0,0,0,0,0,15462,15464,0,15465,0,0,15466,0,0,15467, +0,0,0,0,0,15468,0,0,0,0,15481,0,0,15484,0,15485,15486,0,0,0,15487,0,0,0,0,0, +15488,0,15492,15498,0,0,0,15499,0,0,0,15500,0,15501,0,0,15512,0,15522,0,0,0, +15524,0,15525,15526,0,0,15527,0,0,15545,15546,0,15548,15552,0,15553,0,0,0,15554, +0,15555,0,15557,15565,15573,15577,15578,0,15582,0,15583,0,0,0,0,0,0,0,0,0,0,0,0, +0,15586,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15588,0,0,0,0,0,15589,0,0,0,0,0,0,0,15593, +15594,0,0,0,0,15595,0,0,0,0,0,0,15596,0,0,0,15597,0,0,0,0,15600,0,0,15601,0,0,0, +0,15602,15603,0,0,0,0,0,0,15604,0,15609,0,0,15612,0,0,15613,0,0,15615,15617, +15618,0,0,15620,0,15636,15637,0,0,15649,0,0,0,0,0,0,0,15650,0,0,15651,0,0,0, +15656,0,15658,0,0,0,15664,0,0,15665,0,0,15668,0,0,0,0,0,15669,0,0,15674,0,0, +15675,0,0,0,0,15676,0,0,0,0,0,0,0,0,0,0,0,15677,0,0,0,0,15678,0,0,0,0,0,15679,0, +0,15681,0,15686,0,0,0,0,15687,0,15688,0,0,15690,0,0,0,15697,0,15699,15700,0,0,0, +0,0,0,0,0,0,15701,0,15702,15703,0,15704,0,15705,0,15707,0,15709,0,15712,15716,0, +15717,0,15718,15720,0,0,0,0,0,15724,0,0,0,15725,0,15726,0,0,0,15740,0,15745, +15746,0,0,15747,0,15748,0,0,0,0,0,15749,0,0,0,15752,0,15753,0,0,0,0,0,0,15759,0, +0,0,15765,0,0,0,0,0,0,0,0,0,15767,0,0,0,15771,0,0,15784,0,0,0,0,15785,15790, +15791,0,0,15792,0,0,0,15807,0,15811,0,0,0,0,0,0,0,0,0,0,0,0,15818,0,0,0,15819,0, +0,0,0,15821,0,0,0,0,0,15822,15824,0,0,15827,0,0,15829,15831,0,15832,0,0,15833,0, +15835,15838,15839,15843,0,0,0,0,0,0,0,0,0,0,0,15844,0,0,0,0,15845,15851,15856,0, +0,0,0,0,0,0,15858,15860,0,15861,0,0,0,15864,0,0,0,0,15865,0,0,0,0,0,0,15866,0, +15872,0,0,15876,0,0,0,0,15877,15878,15883,15885,0,0,15888,0,0,0,0,0,15889,15890, +0,0,0,0,0,0,0,0,15892,0,0,0,0,0,0,0,15893,0,0,15894,0,0,0,15895,0,15896,15897,0, +15898,15901,15902,0,15911,15915,0,15916,0,15924,15935,0,15937,0,0,0,0,0,15950,0, +0,0,0,0,0,0,15958,0,0,0,15961,0,0,15966,0,15967,0,0,15977,0,0,15978,0,0,15981, +15982,15983,0,0,0,0,0,0,0,15986,0,0,0,15990,0,15991,15995,15998,0,15999,0,16000, +0,0,0,0,16008,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,16009,16011,0,16013,0,0,0,0, +0,0,0,0,16014,0,0,16015,16023,16024,16025,0,0,16026,0,16030,0,16032,0,16033,0,0, +0,0,0,0,16035,16036,16037,0,0,0,0,0,16039,0,0,0,0,16041,0,0,0,0,0,16043,16044,0, +0,16047,0,0,0,16048,0,0,16049,16050,16052,0,0,0,0,0,16055,0,0,0,0,0,0,0,0,16056, +0,0,0,0,0,0,0,16058,16060,16061,0,0,16063,0,0,16064,0,0,0,16067,16068,0,0,16069, +16078,0,0,0,16079,0,0,0,16080,0,16081,0,0,0,16088,0,0,0,0,0,0,0,0,0,0,0,16089, +16093,0,16097,0,16103,0,16104,16105,0,0,16256,0,0,16259,0,0,0,0,0,0,0,16260, +16261,0,0,16262,0,0,16263,0,16268,0,0,0,0,0,0,0,16269,0,0,16270,16273,0,16274,0, +0,0,0,16275,16276,16277,16280,0,0,0,16281,16284,0,0,0,16286,0,16289,0,0,0,0,0,0, +0,0,0,16290,0,0,0,0,16291,0,0,0,0,0,0,0,16292,0,0,0,0,0,0,0,0,16293,16295,16297, +0,16302,0,16304,0,16305,0,16306,0,0,0,0,0,0,0,0,0,0,0,0,16307,16308,16312,0,0,0, +0,0,0,16313,16315,0,16318,0,0,0,16321,0,0,0,0,0,0,0,16326,16333,16336,0,0,0,0, +16337,16340,0,0,0,0,0,16345,0,0,16346,0,0,0,0,0,0,0,0,0,16347,0,0,16348,0,0,0,0, +16349,0,0,0,16350,0,16357,0,0,0,0,16359,16360,0,0,0,0,16362,16363,16364,16365,0, +0,16366,0,0,0,0,16367,16368,0,16369,16374,0,0,0,0,0,0,0,16376,0,0,0,0,16378, +16379,0,16380,0,0,0,16381,16383,0,0,0,0,0,16390,0,0,0,16399,0,16402,16404,16406, +16407,0,0,0,16409,16411,0,0,0,0,16412,0,16413,16415,16423,0,0,0,0,0,16424,0,0,0, +16428,16434,16435,16449,0,16450,16451,0,0,0,16453,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +16454,0,0,16456,16458,0,0,16459,0,0,16460,0,0,0,0,16462,0,16463,0,0,16466,0,0,0, +0,0,16479,0,0,16480,0,16481,16484,0,0,0,0,0,0,0,0,0,0,16485,0,0,0,0,0,0,16489,0, +0,0,0,0,16491,0,0,16498,0,0,16503,0,16505,0,0,0,0,0,0,0,0,16506,0,0,0,16508, +16509,0,0,0,0,0,0,0,0,16511,16513,0,0,0,16516,0,16517,0,16519,0,16529,0,0,16531, +0,0,0,0,0,0,16534,0,0,16541,16542,0,0,0,0,0,0,0,0,0,16543,16547,16548,0,0,0, +16551,0,16552,0,0,0,16553,0,0,16558,0,0,16562,16565,0,0,0,16570,0,0,0,16573, +16585,0,0,0,16586,16587,16595,0,16596,0,16598,0,0,0,16600,0,0,0,0,0,0,0,0,0,0,0, +0,0,16601,0,0,0,0,16603,0,0,0,0,0,0,0,16604,16612,0,0,0,0,16613,0,16618,0,0,0, +16640,0,0,16641,0,0,0,0,0,0,16645,0,0,0,0,16646,0,0,0,0,0,0,16651,0,0,0,0,16653, +16654,0,0,0,16655,0,0,16656,16667,0,0,0,0,16671,0,16672,0,0,0,16673,0,0,0,0,0, +16676,0,16686,0,0,0,0,16689,0,16690,0,16692,0,16693,0,16694,0,16696,0,0,0,16705, +0,0,0,0,0,0,16707,0,0,0,16709,0,0,0,0,16711,0,16712,16713,0,0,0,16715,0,0,0,0, +16716,0,0,0,0,0,0,0,0,0,16718,16724,0,0,16726,16727,0,0,0,0,0,0,0,16728,0,16729, +0,0,16730,0,0,0,0,0,16731,0,0,0,16732,0,0,0,0,16734,16738,0,0,0,0,0,0,0,0,16743, +0,0,16745,0,0,0,0,0,16749,0,16752,0,0,0,0,16756,0,0,16758,0,16759,0,0,0,0,0, +16760,0,0,0,0,0,0,0,16762,0,16769,0,16770,0,16772,0,0,0,16777,16780,0,0,0,0,0,0, +16781,0,0,16782,0,16784,0,0,16785,16787,16792,0,0,16794,0,0,0,16798,0,0,16809,0, +0,16814,16816,16817,0,16819,0,0,0,0,0,0,0,0,0,0,16820,0,0,16836,16839,0,0,16841, +16851,16857,0,0,16858,16859,0,0,16860,0,0,0,0,0,0,0,0,16862,0,16863,0,0,0,0,0,0, +0,16864,0,0,0,0,0,0,0,16876,0,16881,16882,0,16885,16886,0,16887,0,0,0,16889, +16891,0,0,0,0,0,16894,16895,0,0,0,0,0,0,0,0,0,0,0,16897,0,16898,0,0,0,0,0,16913, +0,0,16924,16925,16926,0,0,16927,0,0,0,16937,16938,0,0,0,16940,16941,0,0,0,16942, +16945,0,16946,16949,16950,0,0,0,16952,16955,0,0,0,16965,0,16969,0,0,16975,0,0, +16976,0,0,0,0,16978,0,0,16981,0,16983,16989,0,0,0,0,16990,0,0,16991,0,0,0,16993, +0,16994,16996,17000,0,0,0,0,0,17002,17004,0,17006,0,0,17007,0,0,0,0,17008,17013, +17014,0,0,0,0,0,0,0,0,0,17021,0,17031,0,0,0,0,0,17033,17036,0,17038,0,0,17039,0, +17045,0,0,17046,17047,0,0,0,0,17048,0,17049,17050,0,17051,17053,0,17054,0,17055, +0,0,0,0,0,17063,0,0,17064,0,0,0,0,0,0,0,17065,0,0,17068,0,0,0,0,0,17072,0,0,0,0, +0,0,17073,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17074,0,17080,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,17081,17083,17084,0,0,0,17085,0,0,0,0,17092,0,0,0,0,0,0,0, +0,0,17093,0,17095,17102,0,0,0,0,0,0,17103,0,0,17105,0,17107,0,0,0,0,17114,0,0,0, +0,0,17115,17125,17127,0,0,17128,0,0,0,17129,17130,0,17131,0,0,0,0,0,17132,17135, +17145,0,0,0,0,0,0,0,0,17146,0,17147,0,17148,0,0,0,0,0,0,17149,17150,0,17151, +17153,0,17155,0,0,0,0,17163,17171,0,17174,0,0,0,0,17179,0,0,17182,17185,0,0,0,0, +0,17186,0,0,17188,0,0,0,0,0,0,0,17189,17191,0,17194,0,0,0,0,0,0,0,0,0,17195, +17196,17203,17204,0,0,17205,17217,0,0,0,0,0,17218,0,0,0,0,17219,0,17220,0,17221, +0,0,17230,0,0,0,0,0,17236,0,17238,17239,0,0,0,17241,17244,0,0,17245,0,17248,0,0, +17251,0,17252,0,0,17264,0,17266,0,0,0,17268,0,0,0,0,17271,17272,0,17273,0,17295, +0,17302,0,17305,0,0,0,17306,0,0,0,0,0,0,0,17308,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +17309,0,17310,17313,0,0,0,0,17314,17315,0,17317,0,0,0,0,17318,0,0,0,0,0,0,0, +17320,0,0,0,0,0,0,17334,0,17344,17348,0,0,0,17350,17351,0,0,17353,0,0,17354,0,0, +0,0,0,0,0,0,0,17355,0,0,0,0,0,0,17356,17357,0,0,17359,0,0,0,17371,0,17372,0,0,0, +17393,0,0,0,0,17394,0,0,0,0,0,17395,0,0,17399,0,0,0,17401,17417,0,17418,0,17419, +0,0,0,0,0,17422,17423,0,0,0,0,0,17424,0,0,0,0,0,17428,17429,17433,0,0,0,17437,0, +0,17441,0,0,17442,0,0,17453,0,0,0,0,0,0,0,0,17454,17456,17462,0,0,17466,0,0, +17468,0,0,17469,0,0,0,0,17470,0,17475,0,0,0,0,0,17479,0,0,0,17483,17484,0,17485, +0,17486,0,17491,17492,0,0,17493,0,17494,17495,0,0,0,17496,0,0,0,17497,0,0,0, +17502,0,0,0,0,0,17503,0,17505,0,17507,0,0,0,17512,17513,17514,0,0,17515,0,0,0, +17519,0,0,0,17522,0,0,17523,0,0,0,0,0,0,0,0,0,17527,0,0,0,17528,0,0,0,17534,0,0, +0,0,17536,0,0,0,17539,0,17540,17543,17549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17556, +0,0,17558,0,17559,0,0,17560,0,0,0,17563,0,0,0,0,0,0,17564,0,0,17565,17566,0, +17567,0,0,0,0,0,0,17569,17570,0,17575,0,0,0,0,0,0,0,0,0,0,0,17581,0,0,0,17582, +17583,0,17586,0,0,17587,0,0,0,0,0,0,0,17588,0,0,0,0,17596,17597,0,0,17598,17600, +0,0,0,0,0,0,17601,0,0,0,17604,0,0,17605,0,0,17607,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,17612,0,0,17618,0,17621,17622,0,0,0,0,17623,0,0,17624,0,0,17630,0,0, +17631,17633,17634,0,0,0,0,0,0,0,17635,0,0,17636,0,0,17637,0,17638,0,17640,0,0,0, +0,0,0,0,0,0,0,17641,0,0,0,0,0,0,0,0,0,0,17643,0,0,0,0,17645,0,0,0,0,0,0,0,0, +17646,17662,0,0,0,0,0,0,0,0,0,17663,17664,0,17665,17666,0,0,0,17669,17671,17673, +0,17679,0,0,0,0,0,0,0,17684,0,0,0,17686,0,17714,0,0,17720,17722,17726,0,0,17728, +0,0,17729,0,0,0,17732,0,17733,0,17734,0,0,0,17735,0,0,0,0,17737,0,0,0,0,17739,0, +0,0,17741,17742,0,0,0,0,17743,17744,17745,0,0,0,17749,0,17750,17751,17752,17754, +17761,17762,0,17763,0,17766,0,17772,0,0,0,0,0,17775,0,0,0,0,0,0,0,17776,0,0, +17777,0,0,17778,17779,0,17782,17783,0,0,0,0,0,0,0,0,0,0,17784,0,0,0,0,0,0,0, +17821,0,0,0,17822,0,0,0,17823,17825,0,0,0,0,0,17826,17831,17832,17833,0,0,17845, +0,0,0,17846,0,0,0,17848,17850,17854,0,17855,0,0,17859,0,0,0,0,0,0,17860,17861,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,17870,17871,0,0,0,0,0,0,17872,0,0,0,17879,0, +0,0,17881,17883,0,17884,0,17885,0,0,17886,0,0,17887,17891,17953,0,0,0,0,17954,0, +0,17955,0,17968,0,0,17972,0,0,0,0,0,17974,0,0,0,0,17976,17978,0,0,17983,0,0,0,0, +18003,0,0,0,0,0,18007,0,0,0,0,0,18009,0,0,0,0,0,0,0,18010,0,0,0,0,0,0,18012,0,0, +18014,0,0,0,18015,0,0,0,18016,0,18017,0,0,0,18030,0,0,0,0,0,0,0,18031,0,0,18036, +18037,18038,0,0,18049,18056,0,18057,18058,0,18059,0,0,0,0,0,0,0,0,18062,0,0,0,0, +18064,0,0,0,0,0,0,0,0,18067,0,0,0,18068,0,0,18075,0,0,18078,18093,18094,0,0,0,0, +0,0,0,0,18097,0,0,0,0,0,18098,18100,0,0,0,18108,0,18111,0,0,18112,0,18113,0,0, +18115,18116,0,18118,0,0,0,0,18121,0,0,0,0,18123,0,0,0,0,0,0,0,0,0,18124,0,0,0,0, +18125,18126,0,18127,0,0,18128,18135,0,0,0,0,0,0,0,0,0,18150,0,0,0,0,0,18151, +18152,0,0,18156,18164,0,18166,18171,0,0,0,0,0,0,0,0,0,18172,18183,0,18184,0,0,0, +0,18185,0,18187,0,0,0,0,0,18188,0,0,0,0,0,0,0,0,18189,0,0,18190,0,0,18191,18192, +0,0,18194,18195,18196,0,0,0,18197,0,18203,0,18204,0,0,0,0,18205,0,0,0,18207, +18208,0,0,18214,0,0,0,18215,18216,0,0,0,18220,0,0,18222,0,0,0,0,0,18223,0,18225, +18231,0,18234,0,18235,0,0,0,0,18240,0,0,18241,18242,0,0,0,0,0,18243,18251,0, +18253,0,18254,0,0,0,18266,0,0,0,0,0,0,18269,18270,18271,18273,18281,0,0,0,0,0,0, +0,0,0,0,0,0,18282,0,18283,0,18284,0,0,0,0,0,0,18285,0,18287,18289,0,0,18290,0,0, +0,0,18308,0,0,0,18310,0,0,0,0,0,0,0,0,0,0,0,0,18311,0,18312,18313,0,18315,0,0, +18316,18320,0,18331,0,18332,0,18336,0,0,0,0,18337,0,18340,0,0,0,0,0,0,0,0,0, +18341,0,18344,18345,0,18346,0,0,0,0,0,18348,0,18351,0,0,18356,0,0,0,0,0,0,18357, +0,0,0,0,0,18367,0,0,0,18368,0,18369,0,18370,18371,0,0,0,18437,18444,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,18445,18450,0,0,0,0,18451,0,18452,0,0,0,18453,0,0,0,0,0,18455,0, +0,0,18456,0,18457,0,18460,0,0,18461,0,0,0,0,0,0,0,0,18466,0,0,18467,0,0,0,0, +18473,0,0,0,18476,0,18477,0,0,0,18478,18479,18480,0,0,0,18485,0,0,0,18486,0,0,0, +0,0,0,18488,18490,0,0,0,0,0,0,18491,0,0,0,0,0,18495,0,0,18496,0,0,0,0,0,0,18505, +0,18521,0,18522,18523,0,0,0,18525,18526,0,0,0,0,0,18527,0,0,0,0,18532,18533,0, +18534,0,0,0,0,0,0,18535,18537,0,18538,0,0,0,0,0,0,18540,18541,18542,18543,0, +18546,0,0,0,0,18553,18556,0,0,18558,0,0,18569,18571,0,0,0,18572,0,18574,0,0,0,0, +18586,0,0,0,0,0,18588,0,0,18589,0,0,0,0,0,0,18590,0,18592,0,0,0,0,18594,0,0,0, +18596,0,0,18597,18598,0,0,18601,0,0,0,0,18602,0,0,0,18603,18604,0,18605,0,0,0,0, +18608,0,0,18611,0,0,0,0,0,0,0,0,0,18612,0,18616,0,0,18617,18619,0,0,0,18628,0,0, +0,18629,0,0,18630,0,0,0,0,0,0,0,18631,0,18632,0,0,18635,18637,0,0,0,0,0,0,18641, +18643,18648,0,18652,0,0,18653,0,18655,18656,0,0,0,18657,0,0,18666,18674,0,0,0,0, +18677,18684,18685,0,0,18686,0,0,18690,0,0,0,0,0,0,0,18695,18696,0,0,0,0,0,0,0,0, +0,0,18697,0,0,18700,0,0,0,0,0,0,18702,0,18708,0,0,18709,0,18710,0,0,18711,0, +18714,0,0,18718,0,0,0,0,0,0,18719,0,0,18722,0,18726,0,0,0,0,0,0,0,0,0,0,0,0,0, +18731,0,0,0,0,0,18739,18741,0,0,18742,0,18743,18744,18746,18748,0,18752,18753,0, +0,18754,18763,0,18765,0,0,0,18766,0,0,0,18769,0,0,0,0,0,18773,18778,18779,18781, +0,0,18784,18787,0,18788,0,18793,0,0,0,0,0,0,18795,0,0,18800,0,0,0,0,0,18801, +18804,0,0,0,0,0,0,0,18806,0,0,0,18811,18815,18816,0,0,0,0,18825,0,0,18827,18829, +0,0,18830,0,0,0,0,18831,0,0,18832,0,0,0,0,18833,0,18840,0,18841,0,18842,0,0,0,0, +18843,0,18844,0,0,0,0,0,0,18845,18846,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +18848,0,0,0,18853,18860,0,0,18862,18866,0,0,18867,18869,0,0,18874,18881,18891,0, +0,0,0,0,0,0,0,0,0,18892,0,0,0,0,0,0,0,0,18895,0,18896,0,0,0,18900,0,0,0,18901,0, +18902,18915,18916,0,0,0,0,0,0,0,0,18919,0,0,0,0,0,18920,0,0,0,18921,18929,0,0,0, +0,18930,0,0,0,0,0,0,18932,0,0,0,0,18934,18942,0,0,0,18951,18957,0,0,0,0,18958,0, +0,0,0,18959,18960,0,0,18961,0,0,18962,0,0,0,0,18963,18964,0,0,0,18965,0,18967,0, +0,0,0,0,0,0,0,0,18968,0,18969,0,18970,18973,18976,0,0,0,0,0,0,18977,0,0,0,18981, +0,0,0,18990,0,18998,0,0,0,0,0,18999,19003,0,0,19005,0,0,0,19006,0,0,0,0,0,0, +19008,19011,0,0,19018,0,0,19019,0,19024,0,19031,19032,0,19039,0,19041,19050,0,0, +0,19051,19055,19056,0,19059,19063,19064,0,0,19088,0,0,0,19093,19094,0,0,0,0, +19095,0,19096,0,0,0,19097,0,0,19098,0,19099,19100,0,0,19103,0,0,0,0,0,0,0,19111, +0,0,0,0,0,0,19112,0,0,0,19116,19117,0,19121,19122,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,19123,19124,0,0,0,0,0,0,0,19125,19126,0,19128,0,0,0,0,0,0,0,0,0,0, +19129,19130,19131,19132,0,0,19146,0,0,19147,19156,19158,0,0,0,0,0,0,0,0,19182, +19185,0,0,19187,0,0,0,19193,0,0,0,0,0,19194,0,19197,0,0,0,0,19198,0,0,0,0,0,0,0, +0,0,0,19202,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19203,0,19205,19210, +0,0,0,19213,0,19218,0,0,0,19223,19229,0,0,19230,0,0,19231,19232,19233,19239,0,0, +0,0,0,19240,0,19248,19249,0,0,0,0,19254,0,19256,19258,19259,0,0,19261,0,19266,0, +0,0,19272,0,19278,19281,19282,0,0,0,0,0,0,0,0,0,0,0,0,19283,0,0,19284,0,0,19285, +19287,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19288,19291,0,19292,0,0,0,0,19297,0,19298,0,0, +0,0,19302,19303,0,0,0,0,19304,19305,0,0,0,0,19314,0,0,19315,0,0,19321,0,0,0,0,0, +0,0,19322,0,19333,0,19334,19335,0,19336,19337,0,0,0,0,0,0,0,0,0,0,0,19346,0,0, +19353,0,19354,19362,0,19366,19367,0,0,19369,0,19375,0,19377,19380,19388,0,0,0,0, +0,19389,19390,0,0,0,0,19392,0,0,0,0,0,19402,0,0,0,0,0,0,0,0,19412,0,0,19413, +19422,0,19424,0,0,0,19425,0,0,0,19428,0,0,0,0,19431,0,0,0,0,0,19432,0,0,0,0,0, +19448,19459,0,0,19461,0,19462,19463,0,19467,19474,19482,0,0,0,0,19494,0,0,0,0, +19501,0,0,0,0,0,0,0,0,0,0,19502,19504,0,0,0,0,0,0,0,19505,0,0,0,0,19506,19507,0, +0,0,19508,0,0,19511,0,0,19514,0,19515,0,19516,0,19518,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,19530,0,19537,19538,0,19543,19546,0,19547,19551,0,0,0,0,0,0,19552, +19553,0,0,0,0,0,0,0,0,0,0,0,0,19555,0,0,19556,0,0,0,0,0,0,0,0,0,0,0,0,19560, +19561,0,0,19562,0,0,0,0,0,0,19565,19567,0,19568,0,0,0,19569,19570,0,19578,0,0,0, +0,19580,0,0,0,0,19581,19584,0,0,0,0,0,0,0,19585,19586,0,0,0,19587,19588,0,19589, +0,0,0,0,0,0,19592,19593,19599,0,19600,0,0,19604,0,0,19605,0,19606,19608,19610,0, +19613,19614,0,0,0,0,0,0,19616,19617,0,0,19618,0,0,19619,0,0,0,19620,19621,19631, +0,0,19632,19634,19636,0,19643,0,0,19644,19658,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,19659,0,0,0,0,0,0,0,0,0,0,0,19675,19677,0,0,0,0,19679,0,19683,0,19684,0,0, +0,0,0,0,19687,0,0,0,0,0,0,0,0,19688,19689,19692,0,0,0,0,0,0,0,19695,19697,0,0,0, +0,0,19698,19699,0,0,19700,0,19702,0,0,19703,0,0,0,0,0,0,19704,19708,0,19710,0, +19713,0,0,0,19715,0,0,0,0,19718,0,0,0,0,0,0,0,19720,0,19722,0,0,19725,0,0,0,0,0, +0,0,0,0,0,0,0,0,19730,0,0,0,0,0,19731,0,19734,19735,19739,0,0,19740,0,19741,0,0, +0,19746,0,0,19747,0,19771,0,0,0,0,0,0,0,0,19772,19775,0,0,0,0,0,0,19778,0,0,0,0, +0,19779,0,0,19780,19790,0,19791,0,0,19792,0,0,0,19793,0,0,19796,19797,0,0,0, +19799,0,0,0,19801,0,0,0,0,19803,0,19804,0,19805,0,0,19807,0,0,0,19808,0,0,0,0,0, +0,19809,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19816,0,19821,0,19822,19830,19831,0,0, +0,19833,0,0,0,0,0,0,0,0,0,0,19838,0,0,0,0,19839,0,0,19843,0,0,0,0,19845,0,0,0,0, +19847,0,0,19848,0,19849,0,0,0,0,0,0,0,19851,0,0,0,19854,0,0,0,0,0,0,0,0,0,19864, +0,19865,0,19866,0,0,0,0,0,0,0,19868,0,0,19870,0,0,19871,0,0,19872,19873,19875,0, +19880,19882,19884,0,0,19885,19886,19888,0,0,0,0,0,0,0,0,0,0,0,0,19890,19892, +19893,0,0,19894,0,0,0,19895,0,19896,19902,0,0,19903,0,0,19905,0,0,0,19906,0, +19908,0,19909,19911,0,0,0,19913,19920,0,19938,19939,19940,0,0,0,0,0,0,0,19942,0, +19943,0,19945,0,0,0,19951,19952,19954,19960,0,19965,0,19971,0,0,0,0,0,19975,0, +19976,0,19990,0,0,19991,0,19993,0,19995,0,0,0,19998,19999,20001,0,20003,20005,0, +20011,20012,0,0,0,0,0,0,20014,0,20020,0,0,0,0,20021,0,0,0,0,0,20023,20024,0,0,0, +0,0,20025,0,0,20027,0,0,20029,0,0,20032,0,0,0,0,20044,20045,0,20048,20049,0,0, +20050,0,20052,0,0,20054,20057,0,0,0,0,0,0,0,0,0,20059,0,0,20061,0,20062,0,20064, +0,0,20066,0,0,20067,0,0,0,0,20069,0,0,0,0,0,0,20070,20071,0,0,0,0,0,0,0,0,0,0,0, +20072,0,0,20073,20074,0,0,0,0,0,20075,0,20078,0,0,0,0,20080,0,20081,0,0,0,0,0,0, +20095,0,20098,0,0,0,0,0,0,0,20107,0,0,0,0,0,0,0,0,20112,0,0,0,20113,20114,0,0,0, +20115,20123,20124,0,0,0,20131,20133,20134,0,0,0,0,20136,0,0,20137,20138,20150,0, +20152,0,0,0,20153,0,0,20154,0,0,0,20158,0,20163,0,0,20164,0,0,0,0,0,0,0,20166,0, +20168,0,20170,0,20175,0,0,20178,0,0,0,0,20223,0,0,0,0,20224,0,20226,0,0,20230,0, +20231,0,0,0,0,20232,0,0,20233,20234,0,20244,0,20247,0,0,0,0,0,0,20249,0,0,0, +20250,0,0,0,0,20251,0,20253,0,20254,0,0,0,0,20256,0,0,20264,0,0,0,0,20266,0,0,0, +20278,0,0,20279,20282,0,0,0,0,0,20283,0,20284,0,20285,0,20287,20290,0,0,0,0, +20292,0,0,0,0,20293,20297,0,0,0,0,0,0,20299,0,20300,20303,0,0,0,0,0,0,20307,0,0, +20308,0,20309,0,20310,0,0,0,0,0,0,20312,0,0,0,20314,0,0,0,0,20315,20316,0,20322, +0,0,0,0,0,0,20339,0,0,0,20342,0,0,0,0,20352,0,0,0,0,0,0,0,0,0,0,20362,0,0,20365, +0,20375,20377,0,0,0,0,0,0,0,0,0,0,0,20378,20379,0,20380,0,0,20381,0,20382,0, +20383,0,20388,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20390,20392,20393,0,0,20395,0,0,0,0,0, +20396,0,0,0,0,0,0,0,0,20398,20415,0,0,0,20417,0,0,20420,0,0,20426,20428,0,20431, +0,0,20432,0,20433,20434,20435,0,0,0,0,20440,0,0,0,0,0,20442,0,20443,0,20446,0,0, +0,0,20448,0,20451,0,0,0,0,0,0,0,0,0,20452,20453,0,0,20454,0,0,0,0,0,0,20457,0, +20458,0,0,0,20465,0,0,0,0,0,20469,0,0,0,20473,0,20476,0,0,0,0,0,0,0,0,20477,0,0, +20485,0,0,20486,0,0,20487,0,20496,0,20497,0,0,20498,0,0,0,0,0,0,0,0,0,0,20499, +20500,0,20501,0,0,0,0,0,20520,20527,0,20529,0,0,0,0,20539,0,0,20540,0,0,0,20543, +0,0,0,20546,0,0,0,0,0,20548,0,0,20563,0,0,20564,0,20566,0,0,0,0,0,20589,0,0,0,0, +20590,0,0,20593,20594,0,0,0,0,20595,0,20597,20598,0,0,0,20618,20620,0,0,0,0, +20621,0,0,0,0,20627,0,0,0,0,0,20628,0,0,0,20629,0,20630,0,0,20639,0,0,0,0,0, +20707,0,0,20709,0,0,0,20713,20714,0,0,0,0,0,20724,20725,0,0,0,0,20726,20728, +20729,0,20733,0,20734,0,20735,20736,0,20737,0,0,20744,0,20745,0,20748,0,0,20749, +0,0,0,0,0,0,0,0,20750,0,0,0,0,20754,0,0,0,20761,0,0,20763,0,0,0,0,0,0,0,20766,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,20767,0,0,0,0,20768,0,20769,20777,0,0,0,0,0,0,20785,0, +0,0,20786,20795,20801,0,20802,0,20807,0,0,20808,0,0,20810,0,0,20811,0,20812,0,0, +0,0,0,20813,0,0,20818,20820,20821,0,0,0,20822,0,20823,0,0,0,20826,0,0,0,0,0,0,0, +20829,20830,20831,0,20832,20836,0,0,20839,0,0,20840,20842,0,20843,0,20844,0, +20854,0,0,0,20855,0,0,0,0,20856,0,0,0,20869,0,0,20871,0,0,0,0,0,0,0,20873,0,0,0, +0,0,20876,0,0,0,0,0,20880,0,0,20882,0,0,0,0,20883,20884,0,0,20890,0,0,0,0,0,0,0, +0,0,20891,0,0,0,0,0,20905,0,20906,20910,0,0,20912,20915,0,0,0,0,0,20916,0,20917, +0,20919,20920,20922,0,20927,0,20928,20929,20930,0,0,20935,0,0,20939,0,0,20941,0, +0,0,20943,0,0,0,20946,20947,0,0,0,0,0,20950,0,20954,0,0,20955,20964,0,0,20967,0, +0,0,0,0,20973,20975,0,0,0,20984,0,20987,20988,0,0,0,0,0,20989,0,0,0,20995,0, +20998,0,20999,0,0,0,0,21000,21001,0,0,0,0,21008,0,21010,0,21016,0,0,0,21017, +21018,0,0,0,0,0,21021,21026,21027,21028,0,0,21029,0,0,0,0,0,21030,0,0,0,0,0,0,0, +0,0,0,0,0,0,21031,21032,0,0,0,0,0,21037,0,0,21038,0,0,0,0,0,0,0,0,0,21039,0, +21041,0,21046,21047,0,0,0,21049,21053,0,0,21057,21064,21065,0,0,21066,21067,0,0, +0,21069,0,0,0,21071,21072,0,0,21073,0,21074,0,0,21078,0,0,0,0,21079,0,0,21080, +21081,0,0,21086,21087,0,21089,0,0,0,0,0,0,0,21091,0,21093,0,21094,0,0,0,0,0,0,0, +0,21095,0,0,0,0,0,21096,0,21098,0,0,0,0,0,0,0,21099,0,0,21100,21101,21102,0,0,0, +0,0,21103,0,21104,0,0,0,0,0,21105,21108,21109,0,0,21112,21113,0,0,0,0,0,0,21115, +21122,21123,0,0,0,0,0,21125,0,0,0,0,0,0,0,0,21129,21131,0,0,21134,0,0,0,21137, +21142,0,21143,0,0,21144,0,21145,21146,0,21152,21154,21155,21156,0,0,0,21160,0,0, +0,0,0,0,21161,0,21164,0,21166,0,0,0,0,21170,0,0,0,0,21171,0,0,21172,0,21174,0, +21175,0,0,0,0,0,21176,21179,21188,0,0,0,21189,0,0,21190,0,0,0,21192,0,0,21193,0, +0,0,21198,0,21212,0,0,21213,0,0,0,0,0,0,21215,21216,0,0,21223,21225,0,21226,0,0, +0,0,21227,21228,0,0,21229,0,0,0,0,21230,21236,0,0,0,0,0,0,0,0,0,0,0,0,0,21237,0, +0,21238,21239,0,0,0,0,21256,0,0,0,0,0,21257,0,0,0,0,0,0,0,21259,0,0,0,21263,0, +21272,0,21274,0,21282,0,0,0,0,0,0,0,0,21283,0,0,0,0,0,0,0,0,21294,0,0,21297,0,0, +0,0,21298,0,0,0,21299,0,21300,21302,0,21316,0,21318,21322,21323,0,21324,0,21326, +0,0,0,21327,21328,0,0,0,21352,0,0,21354,21361,0,0,0,0,0,0,0,0,0,0,0,0,0,21362,0, +0,0,21363,0,0,0,0,0,0,0,0,0,21366,0,0,21367,21372,21374,0,0,0,21375,21377,0, +21378,0,0,0,21380,0,0,0,0,0,0,0,0,0,0,21381,0,0,0,0,0,0,21382,0,21383,0,0,21384, +0,0,21385,0,0,0,0,21389,21390,0,0,0,0,0,0,0,0,0,0,0,0,0,21397,21398,0,0,0,0,0,0, +0,0,0,0,21399,0,21400,0,0,0,0,21402,0,0,0,21403,21404,0,21405,21406,0,0,0,21407, +0,0,0,0,0,0,0,0,0,0,0,0,21408,0,0,0,0,21409,0,21421,0,21422,0,0,0,21425,21428,0, +0,0,0,21429,0,0,0,0,0,21433,0,0,0,0,0,0,0,0,0,0,21434,0,21443,0,21444,21449,0, +21452,0,21453,21454,0,0,0,21457,0,0,21458,0,0,0,21460,21461,0,0,21464,0,0,0, +21473,21478,0,0,21479,0,0,21481,21483,0,0,0,0,0,0,0,0,21484,0,0,21485,21486,0,0, +21488,0,0,0,0,0,0,21523,0,0,21525,0,0,0,0,0,0,0,21526,0,0,0,0,0,0,21529,21530,0, +0,21531,0,0,21533,0,0,21539,21564,0,21567,0,0,0,0,0,0,0,0,21575,0,0,0,0,21577,0, +0,0,0,0,21591,0,0,21604,0,0,0,0,0,0,0,0,0,21605,0,21606,0,0,21617,21618,21619, +21620,0,0,0,0,0,0,0,0,0,0,0,0,0,21623,0,0,0,0,21631,0,21635,0,0,0,0,21639,21646, +21653,21662,0,0,21663,21664,0,21666,0,0,21667,0,21670,21672,21673,0,21674,21683, +0,0,0,0,0,21684,0,21694,0,0,0,0,21695,21700,0,21703,0,21704,0,0,21709,0,0,0, +21710,0,0,0,0,0,0,0,0,21711,0,0,0,21712,0,21717,0,21730,0,0,0,21731,21733,0,0,0, +0,21737,21741,21742,0,21747,0,0,0,21749,0,0,0,0,0,0,0,0,0,0,0,0,0,21750,0,0,0,0, +0,21752,0,0,0,0,21753,0,0,0,0,0,0,21755,21756,0,21757,0,0,0,0,0,0,21760,0,0, +21763,0,0,0,0,0,0,0,0,0,21764,0,0,21766,0,0,21767,0,0,0,0,0,0,0,0,0,21773,0, +21774,0,0,21775,0,0,0,0,21776,0,0,21777,0,0,0,0,0,0,0,0,0,21780,21787,21788, +21791,0,0,0,21797,0,0,0,0,0,21805,0,0,0,0,21806,0,21807,21809,0,21810,21811,0, +21817,21819,21820,0,21823,0,21824,0,0,21825,0,0,21826,21832,0,0,0,0,0,21833, +21848,21849,0,0,21867,21870,21871,21873,0,0,0,21874,0,0,0,0,0,0,0,0,0,21875,0, +21878,0,0,0,21879,0,21881,21886,0,0,0,0,21887,0,0,21888,21894,21895,21897,0, +21901,0,21904,0,0,21906,0,0,0,21909,21910,21911,0,0,21912,0,0,21913,21914,21915, +0,21919,0,0,0,0,0,0,0,21921,0,0,21922,21933,21939,0,0,0,0,0,0,0,0,0,0,0,21944,0, +0,0,0,0,21945,0,21947,0,0,0,0,0,0,0,0,0,0,21949,0,0,0,21950,0,0,0,0,0,0,0,0,0,0, +0,0,0,21951,0,21952,0,0,0,0,0,0,0,0,0,21954,21957,0,0,0,0,21958,0,21959,0,0,0,0, +0,0,21962,21963,0,0,0,0,0,0,0,0,21964,21965,0,0,21969,21970,0,0,0,21974,0,0, +21980,21981,0,21982,0,0,0,0,0,21985,0,21988,0,21992,0,21999,0,0,0,0,0,0,22001,0, +22002,0,0,0,0,0,0,22003,0,0,0,0,0,22004,0,0,0,22008,0,22009,22015,0,0,22016,0,0, +0,22017,22019,0,0,0,0,0,0,0,0,0,22020,0,0,0,0,0,0,0,0,0,0,22021,22037,0,22039,0, +0,0,22040,0,0,0,22048,22049,0,0,22053,22055,22056,22059,0,0,22060,22061,0,0, +22064,0,0,0,0,22066,0,0,0,0,0,0,0,22073,0,0,0,22074,22075,0,0,0,0,0,0,0,22076,0, +0,0,0,22077,22084,22099,0,0,0,0,0,0,0,22104,0,0,22107,0,22108,0,22109,0,22110,0, +0,0,0,0,0,0,22111,22119,0,22120,22122,0,0,0,0,22125,0,0,0,22128,22129,0,0,0,0,0, +0,22141,0,0,0,22142,0,0,22144,22146,0,22148,22149,22151,22154,0,0,0,22162,0,0,0, +0,22164,22177,0,0,0,0,22179,0,22182,22183,0,0,22184,22188,0,0,0,0,0,0,0,0,22190, +0,22194,22201,0,0,22208,0,22209,0,22212,0,0,22215,0,22223,22231,0,0,22232,0, +22234,0,0,22235,22236,0,22237,0,22240,0,0,0,0,0,22241,0,0,0,22242,22246,22247,0, +0,0,22259,22268,0,22269,0,0,0,0,0,0,0,22270,0,0,0,0,22271,0,22272,0,22277,0,0,0, +0,0,22278,22280,22283,22286,0,0,22287,22289,0,0,22290,0,22293,0,0,0,0,0,0,0,0,0, +0,22295,0,22301,22302,0,0,0,22305,0,22308,0,0,0,0,0,0,0,0,0,0,22315,0,0,0,22317, +0,22334,0,0,0,22335,0,0,0,0,0,22336,0,22338,22344,0,22347,22349,0,22350,0,0,0,0, +0,0,0,22357,0,0,0,0,0,22358,0,0,0,0,0,0,0,0,0,0,22359,22360,0,0,0,0,0,0,0,0, +22361,22366,0,0,22369,0,22370,22373,0,0,0,0,0,22375,0,22377,0,0,0,0,0,22378,0,0, +0,0,22381,0,0,0,0,22382,0,22383,0,0,0,0,0,0,0,0,0,22391,0,0,22392,22395,22396, +22402,0,0,0,0,0,0,0,0,0,0,0,0,0,22405,0,0,22406,0,0,22408,0,0,22409,22410,0,0,0, +0,0,0,22424,0,0,0,0,22426,0,0,0,22427,0,22428,0,22432,0,22435,22442,22443,0,0,0, +0,22444,0,0,0,0,0,22446,0,22454,0,22455,0,0,0,22465,0,22470,0,22471,0,0,0,0, +22472,22473,0,22487,0,0,0,22488,0,0,0,0,22489,0,0,22499,0,0,0,0,0,0,22514,0,0, +22515,0,0,0,0,0,0,0,22516,0,0,0,22517,22520,0,0,0,22534,0,0,22535,0,0,22536,0, +22540,22553,0,22555,0,0,0,0,22561,0,0,22562,0,0,0,0,0,0,0,0,0,0,0,22566,0,0,0,0, +22567,22568,0,0,22575,0,22579,0,22582,22583,22585,0,0,0,0,0,22586,0,0,22587,0,0, +22590,0,0,0,0,0,22591,0,22592,0,0,0,0,0,22593,0,22602,0,0,22604,0,0,22609,0,0, +22618,0,0,0,0,0,0,22619,0,22624,22625,0,0,22638,0,0,0,0,0,22639,0,0,22640,0,0,0, +0,0,0,0,22644,0,22645,22647,0,0,0,0,22652,22653,0,0,0,22654,0,22655,0,0,0,22656, +0,0,0,0,0,0,0,0,0,0,22673,22675,22676,0,0,22678,22679,0,22691,0,0,0,0,0,0,0, +22693,0,0,22696,0,22699,22707,22708,0,0,0,0,0,0,0,0,22718,0,22719,0,0,0,0,22723, +0,0,0,22724,22725,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22726,22728,0,0,0,0,0,0,0,0,22729, +0,0,22731,0,0,0,0,22732,22735,22736,0,0,0,0,22739,0,22749,0,0,22751,0,0,0,0,0,0, +0,0,0,0,0,22758,0,0,0,0,0,22760,0,0,0,0,0,22764,22765,22766,0,22768,0,0,0,0,0, +22769,22770,0,0,0,0,0,0,22771,0,0,22772,22775,0,22776,22777,22780,0,0,22782, +22784,0,22787,0,22789,22796,0,0,0,0,0,22798,0,0,0,0,0,0,22802,0,22803,22804,0,0, +0,0,0,0,0,0,0,0,22805,0,0,22810,22811,22814,22816,0,22825,22826,0,22831,22833,0, +0,0,0,0,0,0,0,0,22834,0,22836,22838,0,22839,0,0,0,0,0,22840,0,22847,0,0,0,0,0, +22856,22857,0,22858,22859,0,0,22862,0,0,22864,0,0,0,0,22865,0,0,0,0,0,0,0,0,0,0, +0,22866,0,22867,22868,0,0,0,0,22869,0,22871,0,22872,0,22873,22881,22882,22884, +22885,0,0,0,0,0,0,0,22886,22887,0,22894,0,22895,0,0,0,22900,0,22901,0,0,0,0, +22904,0,0,0,0,22905,22907,0,0,0,22915,22917,0,0,22918,0,0,0,22920,0,0,0,22929, +22930,0,0,0,22941,22942,0,0,0,22943,0,0,0,22944,0,0,0,0,0,0,0,22946,0,22947,0,0, +22954,0,22956,0,0,22962,0,0,0,0,0,0,0,22963,0,0,22964,0,0,0,0,0,0,0,22965,0, +22968,0,0,0,22969,0,0,0,0,0,22970,0,22971,0,0,0,0,0,22978,0,0,22979,0,22987,0,0, +22989,0,0,0,0,0,0,22990,0,23005,0,0,0,0,0,0,0,23006,23007,23008,0,0,23023,23024, +23029,0,0,0,0,23030,0,0,0,0,0,23032,0,0,0,0,0,23035,0,0,0,0,23038,0,0,0,23048,0, +23049,23052,23053,23060,23061,0,23063,0,0,0,0,23067,23068,0,0,0,23069,23073,0,0, +0,23127,0,23128,0,0,0,0,0,23129,0,23138,23141,0,23149,0,0,23150,0,0,0,23152,0,0, +0,0,0,0,0,0,23154,0,0,0,0,23157,23159,23160,0,0,0,0,0,0,0,0,0,0,0,0,23180,0,0,0, +0,23181,0,0,23188,0,23189,0,0,0,0,0,0,0,0,0,0,0,0,23195,0,0,23196,23199,0,0,0,0, +0,0,0,0,0,23202,0,23204,0,23207,0,23209,23210,0,0,0,0,0,0,23227,23229,0,0,23230, +23234,23238,0,0,0,23245,23246,23248,0,0,0,0,23249,23254,0,0,0,23265,0,0,0,0,0,0, +0,23268,0,23276,0,0,0,0,23277,0,23297,0,23298,0,0,0,0,23299,0,23302,0,0,23303, +23312,0,0,23314,0,23320,0,0,0,0,23324,0,23325,0,23328,0,23334,0,0,0,23337,0,0,0, +0,23343,23344,23346,0,23348,0,0,0,0,0,0,0,0,23353,0,0,0,0,23355,0,23356,23358,0, +0,0,23359,23360,0,23361,0,23367,0,23369,0,0,23373,0,23378,23379,0,23382,23383,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,23387,0,0,0,0,0,0,23388,23390,0,0,23393,23398,0,0,0, +23399,0,0,0,23400,0,0,0,0,23401,0,0,0,23415,0,0,0,0,0,0,0,0,23416,0,23422,0, +23443,23444,0,0,0,0,23448,0,23454,0,0,0,0,0,0,23456,0,0,23458,23464,0,0,0,0,0,0, +23465,0,0,0,23470,23471,0,0,23472,0,0,0,23473,23496,0,0,0,0,0,0,0,0,23497,0, +23499,0,0,23502,0,0,23503,0,0,23513,0,0,23515,0,0,0,23517,0,0,0,0,23518,23519, +23521,23524,0,23525,23528,23539,0,0,0,0,0,23541,0,0,23544,0,0,23556,0,0,23557,0, +0,0,0,0,0,0,0,0,0,0,0,0,23559,0,23560,0,0,23561,0,0,23566,0,0,0,0,0,23568,23569, +23570,0,0,0,0,23571,0,23574,0,0,0,0,0,0,0,0,0,0,0,23575,0,23579,0,0,23581,0,0,0, +0,0,0,23587,0,0,0,0,0,0,0,23596,23598,0,0,0,0,23602,23606,0,0,23607,0,23608,0,0, +0,23614,23616,0,0,0,0,0,23618,0,0,23619,0,0,0,0,23621,23626,0,23627,0,0,0,0,0,0, +0,23629,0,23630,0,0,0,0,23634,0,23636,0,0,0,0,0,0,23638,0,0,0,0,23640,23667,0, +23669,0,0,0,23681,0,0,0,0,0,0,0,23682,0,23683,0,0,0,0,0,23684,0,0,0,23685,23689, +0,23693,23694,23700,0,23702,0,23709,0,0,0,0,0,0,0,23712,0,0,0,0,0,23714,0,0, +23715,0,0,0,0,23718,0,0,23720,0,0,0,0,23722,0,0,0,23726,23729,0,23741,23746,0, +23748,0,0,0,0,23749,0,0,0,0,0,23750,0,0,0,0,23751,0,23753,0,0,0,0,23757,23765,0, +0,0,23770,0,0,0,0,0,0,0,23771,0,23772,23781,0,0,23796,0,0,0,0,23798,0,23799,0,0, +0,23802,0,0,23806,0,23807,0,0,23808,0,23809,0,23819,0,0,0,23821,0,23827,0,0,0, +23829,0,0,0,0,0,0,0,23830,0,0,0,0,0,0,23832,23833,23834,23835,0,0,0,0,23837, +23838,0,0,0,0,0,23846,0,0,0,0,0,0,23847,0,0,0,0,0,23879,23881,0,0,23882,23883, +23895,0,23899,0,0,0,0,23901,0,0,0,0,0,0,23902,0,0,0,0,0,23903,23905,0,23906,0, +23907,23918,23919,23920,0,23922,0,23924,0,23927,0,23934,0,23937,23941,0,23942, +23946,0,0,0,0,0,23955,23956,23958,0,0,0,0,0,0,23959,0,23962,23965,0,23966,0,0,0, +0,23967,23968,0,0,23973,0,0,23974,0,0,0,0,23975,0,23976,0,0,0,0,0,0,0,0,0,0,0,0, +0,23977,0,0,0,0,0,0,0,0,23980,0,0,23984,0,23985,0,0,23987,0,0,23988,23990,23991, +0,0,0,0,0,0,23992,0,0,0,0,0,0,0,0,23994,0,0,0,23998,0,0,0,0,0,0,0,0,0,23999,0,0, +24003,0,24004,0,24006,0,0,0,24007,0,0,24008,0,0,0,0,0,0,0,24009,0,0,24010,0,0, +24011,0,0,24013,24014,0,0,24015,24016,24027,0,24028,24029,0,24030,0,0,0,0,0, +24033,24034,0,24035,0,0,24036,0,0,24044,0,24048,24049,24063,24067,0,24068,24070, +0,0,24071,24078,24087,0,24090,0,0,0,24095,0,24098,24101,24104,24106,0,24107,0,0, +0,24108,0,0,0,0,24110,24111,0,24113,0,0,24115,24120,0,0,0,0,0,0,24124,0,24125,0, +24126,0,24127,0,0,0,0,0,24135,0,0,24136,0,24137,24142,0,0,0,24146,0,0,24147, +24149,24154,0,24163,0,0,0,24165,24166,24167,0,0,0,0,0,0,0,0,0,0,24169,24170, +24175,0,0,0,24178,0,0,24179,0,0,24181,0,24184,24197,0,24201,24204,0,0,0,0,0,0, +24206,24212,24220,0,0,0,24224,0,0,0,0,0,0,0,0,24226,0,24234,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,24235,0,24236,0,0,0,0,0,24239,24240,24241,0,0,24248,0,0,24249,0, +24251,0,0,0,0,0,0,24253,0,24268,0,0,0,24269,0,24271,24272,0,0,0,0,24273,0,0, +24274,0,0,24279,0,0,0,0,0,0,0,24280,0,24293,24294,0,0,0,0,0,0,24296,0,0,24323,0, +0,0,24329,24330,24331,24339,0,24351,0,0,24369,24370,0,0,0,24371,0,0,0,0,24372, +24373,24374,0,0,0,0,0,24378,0,0,0,0,24379,0,24381,0,24383,24389,0,24390,0,0, +24394,24395,24400,0,0,0,24401,24402,0,24406,0,0,0,24411,0,0,0,24415,0,24416,0,0, +0,0,0,24417,0,24419,0,24422,0,24423,24428,0,24435,0,0,0,24439,0,0,0,24440,24442, +24446,0,0,0,24447,24448,24449,24452,0,0,0,0,24453,24457,0,0,24458,24459,24460,0, +24465,0,0,0,0,0,0,0,24470,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24471,0,24473, +24474,24475,24476,0,24478,0,0,0,0,24480,0,0,0,0,0,0,0,0,0,0,24481,0,0,0,0,0,0,0, +0,0,0,24482,24485,0,0,0,0,24486,0,0,0,24488,0,0,0,24494,0,0,0,0,24497,0,0,24498, +0,0,0,24499,24506,0,0,0,24507,0,0,24511,0,0,24513,24514,0,0,0,0,0,24517,0,24518, +0,24520,0,24521,24524,24525,0,0,0,0,0,24527,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24528,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24537,24539,0,24540,0,0,0,24548,0,0,0,0,0,24549, +24550,0,0,0,24553,24554,0,24555,0,24556,0,24558,0,0,0,0,0,24560,0,0,0,24561,0,0, +0,0,0,24562,0,0,0,0,0,0,0,0,0,0,0,0,0,24567,0,0,0,0,0,24569,0,0,0,24574,0,24575, +0,0,0,0,0,0,0,0,0,0,0,24577,24581,0,24584,0,0,0,0,0,24585,0,0,0,0,0,24586,0,0, +24587,0,24588,0,0,0,0,0,0,0,0,0,0,24590,24591,0,0,0,0,24592,0,0,0,0,0,0,0,24594, +0,0,0,0,0,0,0,24596,24597,0,0,0,0,24602,24603,0,0,0,0,24604,0,0,24605,0,24610,0, +0,24611,0,0,0,0,24612,24615,24616,24624,0,0,0,24627,0,24638,24639,0,0,0,0,24640, +0,0,0,24655,24656,24657,0,0,0,0,0,0,0,0,24662,0,24663,24664,0,0,0,0,0,24665,0,0, +0,0,24667,0,0,0,0,0,0,24668,24669,0,24670,24674,0,0,0,24675,0,24678,0,0,24679,0, +0,0,24681,0,24683,0,0,0,0,24684,0,24685,0,0,24686,0,0,24688,24689,0,0,0,0,24690, +24691,0,0,0,0,0,0,0,24697,0,24698,0,0,0,0,0,0,0,0,24709,0,0,0,0,0,24710,0,24712, +0,0,0,0,0,0,24713,24714,0,24715,0,24716,24718,0,24719,0,0,0,0,24720,0,0,24725,0, +0,24738,0,24749,24750,0,0,0,24752,0,0,0,24753,0,0,0,24758,0,0,0,0,0,24762,0, +24763,0,0,0,0,0,0,0,24764,0,0,0,0,0,24765,24767,24768,0,24772,0,0,0,0,24773,0,0, +0,0,24777,0,0,0,0,0,24785,0,24786,24788,0,0,0,24789,0,0,0,0,24794,24798,0,24799, +24800,0,0,0,24803,0,24804,24806,0,24807,0,0,0,24810,0,0,0,0,0,0,24827,24828,0, +24835,0,0,0,0,0,0,24836,0,0,0,0,0,24839,0,24843,24844,0,0,0,0,0,0,0,0,0,0,24847, +0,0,24848,0,0,0,0,0,0,24849,0,24850,24851,0,0,0,24852,0,24853,0,0,0,0,0,0,0,0,0, +24854,0,24855,0,0,24868,0,0,0,24883,0,0,0,24884,0,24895,24897,0,0,0,0,0,24899,0, +0,0,0,0,24900,0,24913,0,0,0,0,0,0,24914,0,0,24917,24930,24931,0,0,0,24932,0,0, +24939,0,0,24942,0,0,0,0,0,0,0,0,0,24945,24950,0,24951,0,0,24953,0,0,0,24954,0, +24959,0,0,0,24961,0,0,24962,0,24964,24968,24970,24972,0,0,0,0,0,24976,0,0,0, +24977,0,24982,0,0,24983,0,0,24984,0,0,0,24993,0,0,0,24994,0,0,25001,0,0,0,25003, +0,0,25018,0,0,25023,0,0,0,25034,0,0,25035,25036,0,25037,0,0,0,0,0,0,0,25039,0,0, +0,0,0,25040,0,0,0,0,0,0,0,25042,0,0,25043,25045,0,0,0,0,0,0,25049,0,0,25051,0, +25052,25053,0,0,25054,0,0,0,25055,0,0,0,0,25057,25059,0,0,25060,25064,0,25065, +25069,25070,0,0,0,0,25072,0,25073,0,25090,0,0,25092,25093,25101,0,0,0,0,0,0, +25105,25108,0,0,25113,0,0,25115,25116,0,0,0,0,0,0,25117,0,0,0,25120,25121,0,0,0, +0,0,0,0,25125,0,0,0,25126,0,25130,25134,0,25139,0,25143,0,0,0,25151,0,25161,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25163,0,0,0,0,0,0,0,25174,0,25175,0,25207,0,0, +0,25209,0,0,0,0,25213,0,25219,0,25223,0,25225,0,0,0,25227,0,0,0,25228,0,0,0, +25229,0,0,0,0,0,0,0,25231,25233,0,0,0,0,25237,25239,0,0,0,25243,0,0,0,25252,0, +25257,25258,0,0,0,0,25260,25265,0,25268,0,0,25273,25324,0,25325,0,25326,0,0,0,0, +0,0,0,0,25327,0,0,0,0,0,25328,0,0,0,0,0,0,25332,0,0,0,25333,0,0,0,25336,25337, +25338,0,0,25343,0,25350,0,0,0,0,0,0,0,25352,0,25354,0,25375,0,25379,0,0,0,0, +25384,0,0,0,0,0,0,0,0,0,25386,0,25388,0,25390,0,0,25399,0,0,25401,0,0,0,25402,0, +0,0,25407,0,0,0,0,0,0,0,0,0,0,0,25413,25415,0,0,25417,0,0,0,0,0,0,0,25419,0,0,0, +25421,0,0,0,25424,0,0,0,0,25433,0,0,0,0,0,0,0,0,0,25435,0,0,0,0,0,0,25436,0,0,0, +25437,0,0,25440,0,0,0,0,0,0,25442,0,0,25443,0,25446,0,0,25449,0,0,0,25450,0,0,0, +0,25452,0,25453,25454,25455,0,0,0,25456,0,25457,0,0,0,25459,0,25461,0,25468,0,0, +0,0,0,0,0,0,25469,0,0,0,0,0,25471,0,0,0,0,0,25474,0,0,0,0,0,0,0,0,25475,0,0,0,0, +25477,0,0,0,0,25483,0,0,0,0,0,25484,0,0,0,0,0,0,0,0,0,0,0,0,25485,0,25497,0,0, +25498,0,25504,0,25510,0,25512,0,0,25513,25514,0,0,0,0,0,0,25517,25518,25519,0, +25520,0,0,0,0,0,0,0,25521,0,25522,25527,25534,0,25536,0,25537,0,0,25548,25550,0, +0,25551,0,25552,0,0,0,0,0,25554,0,25555,0,25556,25557,25568,0,0,0,25570,25571,0, +0,0,0,0,0,25574,0,0,0,0,25579,0,0,0,25581,0,0,0,25582,0,0,0,0,0,0,0,0,0,25588,0, +0,0,0,25589,0,0,0,0,25590,0,25591,25592,25593,0,25594,0,0,0,25596,0,25597,25615, +0,0,0,0,0,25618,0,0,0,0,25619,25623,0,0,25629,0,0,25631,0,0,0,25635,25636,0,0, +25649,0,0,0,0,25654,0,0,0,25661,25663,0,0,25671,0,0,25678,25698,0,25699,25702, +25703,0,0,0,0,0,0,0,0,25704,0,0,0,0,0,25706,0,0,25710,0,25711,0,25712,0,25715, +25716,25717,0,0,25718,25728,25732,0,0,0,25734,0,0,0,0,0,0,0,0,0,25737,0,0,25739, +0,0,0,25740,0,25741,25745,0,25746,0,25748,25772,25778,0,0,0,0,0,25780,0,0,0,0, +25781,0,25782,25784,25785,0,0,0,25789,0,0,0,0,0,0,25797,25801,0,0,0,25808,25809, +0,0,25811,25814,25815,0,0,25817,0,0,0,0,0,0,0,0,25820,0,0,0,0,25832,25833,0,0,0, +25846,0,0,0,25847,25848,0,0,0,0,0,0,0,0,0,25849,25850,0,0,25851,0,0,25852,0, +25862,0,0,0,25863,25865,0,0,0,0,0,0,0,25867,25868,0,25869,25874,0,25875,0,25876, +25877,0,0,0,0,25878,25902,0,0,0,0,0,0,0,25903,25904,25905,0,0,0,25908,25909,0,0, +0,0,25910,0,0,0,0,0,0,0,25912,0,25913,0,0,0,0,0,0,0,0,25914,0,0,25916,0,0,0,0,0, +25917,25927,0,0,0,0,25928,0,0,25930,0,0,0,25933,0,0,25938,25942,0,0,0,0,0,0,0, +25945,0,25950,0,25956,0,0,25961,25962,0,0,25963,0,25964,25965,25966,0,0,0,0,0, +25967,0,0,0,0,25968,0,0,0,25969,25971,0,0,0,0,0,25973,25975,0,0,0,0,0,0,0,25978, +0,25981,0,0,0,25982,0,0,0,25984,0,0,0,0,0,0,0,25993,0,0,0,0,0,0,0,0,0,0,0,0,0, +26002,0,0,0,26005,0,0,0,26006,26007,0,0,26014,26015,26016,0,0,0,0,0,0,26017, +26018,26020,0,26022,26023,0,0,0,26024,26028,0,26029,26033,26034,26044,0,0,0,0,0, +26046,0,0,26047,0,0,26049,0,26050,0,26051,0,0,0,0,0,26053,0,0,0,0,26054,26059,0, +0,0,0,0,0,26060,0,26066,0,0,0,0,0,0,0,0,0,0,0,0,26067,0,26069,0,0,26071,0,0,0, +26073,0,26074,26077,0,0,0,0,26078,0,0,0,26079,0,26090,0,0,26094,0,0,0,0,0,0,0,0, +26095,0,0,0,0,0,0,0,0,0,0,0,26096,26101,0,26107,26122,0,26124,0,0,26125,0,0,0,0, +0,0,26136,26141,26155,0,0,0,0,0,0,0,0,0,26164,26166,0,0,0,26167,0,26170,26171,0, +0,26172,0,0,26174,0,0,0,0,0,0,0,0,0,0,0,0,0,26175,0,0,0,26176,26177,0,26321, +26322,0,26323,0,0,26324,0,0,0,0,0,0,0,26325,0,26331,0,0,0,0,0,0,26335,0,0,0, +26350,0,0,0,26379,0,0,26382,26383,26385,0,0,26392,26406,0,0,0,0,26411,0,0,0,0,0, +26412,0,0,26420,0,0,26423,0,26424,26426,26432,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +26435,0,26436,0,0,0,0,0,26441,0,26444,0,0,0,26446,0,0,0,0,26447,0,0,0,0,26449,0, +26450,26452,0,26453,26454,0,0,0,26455,0,0,0,26456,0,0,26458,0,0,26460,0,26463,0, +0,0,0,0,0,0,0,26464,26470,0,0,0,0,0,0,0,0,0,26473,0,0,26474,0,0,0,0,0,0,0,26475, +0,0,0,0,0,0,0,26477,0,26485,0,0,26486,0,26487,0,0,26488,26493,26494,0,0,26495,0, +26497,26504,26506,0,0,0,0,0,26507,0,0,0,0,0,26509,0,0,26510,0,0,0,0,0,0,0,0,0,0, +0,0,0,26512,0,26513,26515,0,0,0,26518,0,0,0,26519,0,26524,26526,0,0,0,26527,0, +26532,0,26533,26537,26558,0,0,0,26559,0,0,0,26571,0,0,26573,0,26588,0,26593,0,0, +0,0,0,0,26603,0,26604,0,0,0,0,0,0,0,0,0,0,26606,0,0,0,0,0,0,0,26607,26609,26611, +26614,0,0,0,26616,26620,0,26621,0,0,0,0,0,26627,0,26629,0,0,26630,0,0,26632, +26643,0,0,0,26644,0,0,0,0,0,0,0,0,0,26646,26647,0,0,0,26650,0,0,26656,0,0,0,0, +26663,26670,26671,0,0,0,26685,26686,26687,0,26689,0,0,0,0,26744,0,26745,0,26747, +26748,0,26749,26750,26751,0,0,0,0,26752,26755,0,0,0,26756,26769,0,0,0,26774,0,0, +0,0,0,26775,0,26777,26778,0,26786,0,0,0,26787,0,0,0,0,0,0,0,0,0,0,0,0,0,26788,0, +0,26789,0,0,0,0,0,26791,0,26792,26793,0,0,0,26794,0,26797,26798,0,0,0,26800,0,0, +26803,0,26804,0,0,0,0,0,0,0,0,0,26805,0,0,26808,0,0,26809,0,0,0,0,0,0,0,26812,0, +26825,0,0,0,0,0,0,0,26826,0,0,26827,26829,26834,0,0,0,0,26835,0,0,26849,0,26851, +0,0,0,0,0,0,0,0,0,26852,0,26853,26857,0,26858,0,26859,0,0,0,0,0,0,0,26876,0, +26878,26882,26883,0,0,0,0,26890,26894,0,0,0,0,26895,26896,0,0,0,0,0,26900,0,0,0, +0,0,0,0,26911,26913,26914,26915,26916,26919,0,0,0,26921,26922,0,0,26925,0,0,0, +26928,0,0,26929,26930,0,0,0,26931,0,26932,0,0,0,0,0,26933,0,0,0,0,0,0,26937,0,0, +26943,0,0,26944,0,0,0,26946,0,0,0,0,0,0,0,26956,0,26958,0,0,26963,0,0,0,0,0,0,0, +26965,0,26969,26970,26972,0,0,0,0,0,26973,0,26974,0,26978,0,26980,0,0,0,0,0,0, +26982,0,26986,26987,0,26990,0,0,0,0,27003,27006,0,0,27007,27010,27012,27013,0,0, +0,0,0,0,0,0,27014,27015,27018,0,27019,0,0,0,0,0,27025,0,0,0,27026,0,0,0,0,27029, +27030,27031,27034,0,0,27036,27037,0,0,0,27038,27042,0,0,0,27044,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,27045,0,0,0,0,0,0,0,27046,0,0,0,0,0,0,0,27047,27049,0,27050,0,0,0, +27051,27052,0,27055,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,27056,27058,27059,0, +27061,0,27064,0,0,0,0,0,27069,0,0,27070,0,0,0,0,0,0,0,27072,0,0,0,0,0,0,0,0, +27076,0,0,0,0,0,27078,0,27079,0,0,0,27081,0,0,0,0,0,0,27082,0,27083,27086,0,0,0, +0,27087,0,0,0,0,0,27088,27090,0,27094,0,0,27095,0,27099,27102,0,0,0,27103,0,0,0, +0,27105,0,0,0,27106,0,0,0,0,0,0,27107,0,0,0,0,27108,27117,0,0,0,0,27118,0,0, +27124,0,27126,0,0,27130,27131,0,0,0,0,0,0,27147,0,0,0,0,27148,27149,0,0,0,0, +27150,27151,0,27152,0,27159,0,0,0,27164,0,0,0,0,0,0,0,27175,0,27189,0,0,27191,0, +27193,0,27195,0,27198,0,0,0,0,0,27200,0,0,0,0,27202,0,0,0,0,27203,0,0,27204,0,0, +27206,0,27207,0,0,0,0,27209,0,0,0,27213,0,0,27216,27219,27220,27222,27223,0, +27224,0,27225,27226,0,0,27233,0,0,0,0,27235,0,27237,0,27238,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,27239,0,27242,27243,0,27250,0,0,0,27251,0,27253,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,27254,27255,27258,0,0,0,27259,0,0,0,0,0,0,27267,0,27276,27278, +0,0,0,0,0,0,0,0,0,27296,27297,27301,0,0,0,0,0,0,27302,0,0,0,0,0,0,27312,27313,0, +0,0,0,0,27318,0,27320,0,27329,0,27330,27331,0,27332,0,0,0,0,27340,0,0,0,27348,0, +0,0,0,0,0,27350,0,27351,0,0,0,0,27355,0,0,27358,27359,27361,0,0,0,27365,0,27367, +0,27376,27378,0,0,27379,0,0,0,0,0,0,27396,0,27397,27404,0,0,0,0,0,27408,0,0,0,0, +27453,0,0,0,27456,0,0,0,27458,0,0,0,0,0,0,0,27459,0,0,0,27460,0,0,27461,0,27465, +27467,0,0,27469,0,27470,0,27471,0,27477,27482,0,0,0,0,0,0,27484,0,0,0,0,0,0, +27485,0,0,0,0,0,27493,0,27494,27502,0,0,0,0,0,0,0,0,0,0,0,0,27511,27532,0,0,0, +27533,27545,0,0,0,27546,0,0,0,0,0,0,0,0,0,0,27547,0,0,27549,27550,0,27551,0,0,0, +0,0,0,0,27555,0,0,27571,0,27573,27574,27575,27577,0,27578,0,0,27579,27585,0,0,0, +0,0,27586,0,0,27588,27589,0,0,0,0,27596,0,0,27600,0,0,0,0,0,0,0,0,0,0,0,27608,0, +0,0,0,0,0,0,0,0,0,0,27610,0,0,0,27618,0,0,27620,0,0,0,27631,0,0,27632,27634,0, +27636,27638,0,0,0,27643,0,27644,27649,0,0,0,0,0,0,0,0,0,0,0,0,0,27651,27660,0, +27661,0,0,0,0,0,0,0,27662,0,0,27664,0,27665,0,0,0,27669,0,27671,0,0,0,27673, +27674,0,0,0,27682,0,0,0,27711,0,27712,27713,27719,27720,0,0,27728,0,27729,0,0,0, +0,0,0,0,0,0,27731,0,0,27732,0,27733,0,27738,0,0,0,27742,0,0,0,27743,27744,0,0,0, +0,0,0,27745,27746,0,0,0,27747,27748,27751,27752,0,0,0,27768,27770,0,0,0,27774, +27775,0,27776,27777,0,0,27781,0,27784,0,27786,0,0,27791,0,27792,27793,27804,0, +27812,27813,0,0,0,0,0,0,0,0,27814,0,27825,0,27827,0,0,0,0,27828,27861,27862,0,0, +0,27864,0,0,0,27865,27884,0,27889,0,0,0,0,0,27890,0,27891,0,0,0,27892,0,0,0,0,0, +27897,27898,0,0,27899,0,0,0,27901,27905,0,0,27920,0,0,27921,0,27922,0,0,0,27931, +27934,0,0,0,0,0,0,0,0,0,0,27941,0,27942,0,27945,0,27947,27954,0,0,0,0,27960, +27963,0,0,0,0,0,0,0,0,27964,27965,0,0,0,27967,0,27969,27975,0,27976,27977,0, +27981,0,27983,28051,28052,0,0,0,0,0,28056,0,0,0,0,0,0,28058,28059,0,0,28061,0,0, +0,0,0,0,0,28063,0,0,0,0,0,0,28066,0,0,0,0,0,0,28069,28070,28072,0,28073,0,0, +28074,0,0,0,0,28075,0,0,0,0,0,0,0,28078,0,0,0,0,28085,0,0,0,0,28086,0,0,0,0,0,0, +28088,0,0,0,0,0,0,0,0,28090,0,28097,28114,28115,0,0,0,0,0,0,0,28116,0,0,0,0,0, +28118,0,28129,0,28131,0,0,28135,0,0,0,28140,28141,0,0,0,28146,0,0,0,0,28152,0,0, +0,0,28155,28157,28161,0,0,0,0,28166,0,28167,0,0,0,0,0,0,0,0,0,0,0,28172,0,0,0,0, +0,0,28173,0,0,28175,0,0,0,0,0,0,0,0,0,28178,28188,0,28190,0,0,0,0,0,28191,0, +28193,28206,0,0,28207,28209,0,28211,0,28213,0,0,0,28215,28216,28217,0,28222,0, +28223,28225,0,0,0,28226,0,28227,28229,28232,0,0,0,0,0,0,0,0,0,28235,0,28241,0,0, +28242,0,0,0,0,28243,0,0,0,28245,0,0,0,28248,28250,0,28251,28252,0,0,0,0,0,0, +28253,0,0,28254,28255,0,0,28256,0,0,28258,0,0,0,0,0,28259,0,0,28260,0,0,28261,0, +0,0,0,28262,28263,0,0,28264,0,0,0,28266,0,28268,28269,0,28270,28272,28274,0, +28277,28278,0,0,0,28279,0,28280,28281,28283,0,28292,0,28294,0,28297,0,0,0,0, +28299,0,0,0,0,0,28300,0,0,0,0,0,0,0,28301,0,0,0,0,0,0,0,0,0,0,0,0,0,28302,28303, +0,0,0,0,28304,0,0,28305,0,28312,0,28313,28314,0,0,0,0,0,0,28315,0,0,0,28320, +28321,0,0,28328,0,0,0,28329,28338,0,28339,0,0,28344,0,0,0,0,0,0,0,0,28347,0,0,0, +0,0,0,0,0,28348,0,0,0,0,0,28411,0,28412,28413,0,28416,0,0,0,28420,0,0,0,0,0, +28421,0,0,0,0,28423,0,0,0,28424,0,0,28428,0,0,0,0,0,28429,0,0,0,28431,28434,0, +28458,0,0,0,0,0,0,0,0,0,0,0,28464,0,0,0,0,28465,0,28467,0,0,0,0,0,0,28471,0,0,0, +0,28474,0,28480,0,28481,0,0,28485,0,0,0,0,28486,28488,0,0,28489,0,0,0,0,28492,0, +0,0,28495,0,28497,0,28499,0,0,0,0,28500,0,0,28502,28503,0,0,0,28508,0,0,0,28510, +0,0,28512,28513,28514,28521,0,28526,0,28527,28528,0,0,0,0,28529,0,0,28532,0,0, +28537,28538,0,0,0,28539,0,28548,0,28553,28554,0,0,0,0,0,0,0,0,0,0,0,0,28560, +28563,0,0,28564,0,0,0,0,28565,0,0,0,0,0,0,0,28566,28568,0,0,0,0,0,0,28569,0,0,0, +28570,0,28572,28573,0,0,0,0,28575,0,0,0,0,28576,28581,28588,0,0,28589,0,0,0, +28590,28595,0,28598,0,0,28601,0,0,28605,0,0,0,0,28614,28615,28619,0,0,0,0,0,0, +28620,0,28626,0,0,28628,0,28631,0,28632,0,0,0,0,0,0,28635,0,0,0,28637,28638,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28639,0,28643,0,0,28652,0,0,0,28662,0, +28670,28671,0,0,0,0,0,0,0,0,0,28672,28673,28675,28676,0,0,0,0,0,0,0,28691,0,0,0, +28695,0,0,0,28696,0,28697,28698,0,28705,0,28707,28708,28710,0,0,0,0,0,0,0,28711, +28728,0,0,0,28736,0,0,0,28737,0,0,0,0,0,0,0,0,0,28738,0,28739,0,28741,0,0,28742, +0,0,0,0,0,0,0,0,0,0,0,28745,0,0,0,0,0,0,28749,28750,28752,28754,28756,0,28757,0, +0,0,0,28759,28760,0,0,0,0,0,0,28762,0,0,0,28764,0,0,0,0,0,0,28766,0,28767,28768, +0,0,0,0,28769,28770,0,0,0,0,0,0,0,0,0,0,0,0,0,28771,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,28772,0,28773,0,28782,0,0,0,0,0,0,28784,0,28785,0,28786,0,0,0,28787,0,0,0, +28797,0,0,0,0,0,0,28799,0,0,28801,0,0,0,0,28802,0,28805,0,0,28806,0,0,28807,0,0, +0,0,0,0,0,28808,0,0,0,0,0,28810,28812,0,0,28816,28819,0,0,28821,0,28826,0,0,0, +28842,28852,0,0,28853,0,28854,28855,0,0,0,28857,0,0,0,28858,0,28867,28868,28869, +0,0,0,28874,28880,28882,28890,28892,0,0,0,0,0,0,0,28895,0,0,0,28898,28899,0,0,0, +28900,0,0,28904,0,28906,0,0,0,0,28907,0,0,0,0,0,0,28908,0,0,0,28910,0,28914,0,0, +0,0,0,0,0,28915,28916,28919,0,0,28920,0,28921,0,0,0,0,0,0,0,0,28924,0,0,0,0, +28926,28929,0,0,0,28930,0,28936,0,28939,0,0,0,0,28942,0,0,0,0,0,0,28956,0,0,0, +28966,0,0,0,0,28967,0,0,0,0,0,0,0,0,0,28968,0,28971,0,28975,28976,0,28982,28983, +0,0,28984,28989,28996,28997,28998,0,0,0,0,0,0,28999,0,0,0,0,0,29000,0,29001,0,0, +0,29009,0,0,29011,0,0,29021,0,0,0,0,29024,0,29025,0,0,0,0,0,29026,0,0,0,29036,0, +0,0,29037,0,0,0,0,29038,0,29045,0,29047,0,0,0,0,0,0,0,0,0,29051,0,0,0,29054, +29056,29062,0,29070,29082,0,0,0,29083,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29084,0,0, +0,0,29085,29088,0,0,0,0,0,0,0,29090,29097,0,0,0,29103,0,0,0,0,0,0,0,0,29105,0,0, +0,0,0,29107,0,29109,0,0,0,29115,0,0,29120,0,0,29138,29140,0,0,0,0,0,0,0,0,0, +29152,0,29160,29174,0,29176,0,0,29180,0,29181,0,0,0,0,0,0,0,0,29228,0,0,29229,0, +0,29230,0,0,0,0,0,0,0,0,0,0,29234,0,0,0,29241,0,29245,0,29248,0,29250,29256, +29280,0,29282,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29285,0,0,29286,29291,29292,0,0,0,0, +29294,0,29295,0,0,0,0,0,29296,29297,29298,29300,0,29302,0,0,29304,29307,0,29312, +0,0,0,29322,0,0,29323,0,0,29324,29326,29328,0,29335,0,0,0,0,0,0,0,29338,29339,0, +0,0,0,0,29341,29343,0,0,0,0,29344,0,0,0,0,0,29345,0,0,0,0,29346,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,29347,29348,29349,0,0,29354,0,0,29355,0,0,0,0,0,0,0,0,29357,0,0, +0,0,29364,0,29365,0,0,0,0,0,0,0,29366,0,0,29368,0,0,0,0,0,0,0,0,29378,0,29381,0, +0,0,0,0,0,0,0,29386,0,0,0,0,0,0,29389,0,0,0,29390,0,0,29391,29397,0,29398,29412, +29414,29418,29419,0,0,0,0,0,0,0,29420,0,0,0,0,0,0,0,29423,0,0,0,29435,0,0,0, +29437,0,0,29439,0,29441,0,0,0,0,29443,0,29446,29450,29452,0,0,0,0,0,29456,0,0,0, +0,0,29461,0,0,0,29464,0,0,0,0,0,0,0,0,29468,0,29473,0,0,0,29486,0,0,0,29490,0,0, +0,29491,29492,0,0,29497,0,0,0,29498,0,29499,0,29502,29505,0,29509,0,0,0,29510,0, +0,0,29512,0,0,0,29516,0,0,0,0,0,0,0,0,29518,0,29519,0,0,0,0,0,29520,29521,29529, +0,0,0,0,0,0,0,0,29530,0,0,29531,29538,0,29540,0,0,0,29542,0,29543,29544,29547,0, +0,29548,0,0,0,29549,0,0,0,29550,0,0,29552,0,0,0,0,29558,29561,0,29562,29564,0,0, +29565,0,0,29566,0,0,0,0,0,0,0,0,0,0,29578,29584,29586,29591,0,0,0,0,29593,29594, +0,0,29597,0,0,29613,0,29614,0,29615,0,0,0,0,29616,29617,0,0,29625,0,0,0,29632,0, +0,0,0,0,0,0,29633,0,0,0,0,0,29634,29635,29637,0,29638,0,29641,29643,0,0,0,0,0,0, +29644,0,29645,0,29649,0,0,0,29650,0,29653,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29656, +29659,0,0,29660,0,0,0,29661,0,0,0,0,0,29664,0,0,0,29671,29673,0,0,0,0,0,0,0, +29675,0,29677,29679,0,0,29684,0,0,0,0,0,29685,0,0,0,29687,0,0,0,29688,0,29689, +29690,29700,0,29701,0,0,0,29702,0,29706,0,0,0,0,0,0,0,29720,0,29721,0,29727,0, +29733,29734,0,29750,29761,0,29763,0,0,0,0,0,29764,0,0,29765,0,0,0,29771,0,0,0,0, +0,0,0,0,0,0,0,0,29772,0,0,0,29773,29774,29775,0,0,0,0,0,0,0,0,0,0,0,29822,0,0,0, +29824,0,29825,0,0,0,0,0,29827,0,0,0,0,0,0,0,0,29829,0,29832,29834,0,0,29835,0,0, +29837,29838,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,29843,0,0,0,0,29844,29845,0,0,0, +0,0,0,0,0,0,29849,0,0,29869,29872,29890,29905,0,0,0,0,0,29907,29921,0,29922,0,0, +29923,29926,29944,29946,0,0,0,0,0,0,0,29947,29948,0,0,0,29951,0,0,0,0,0,29953,0, +0,29956,0,29957,0,0,29962,0,0,0,0,29971,0,0,0,29972,0,0,0,0,0,29978,0,29979, +29992,30007,30008,30010,0,0,0,30013,0,0,0,0,30014,30016,0,0,0,0,0,0,0,0,0,0,0, +30017,0,0,0,0,0,30023,30031,0,0,30033,0,0,0,0,0,0,0,0,0,0,30034,0,30038,0,30039, +0,30040,0,0,0,0,0,0,30067,30068,0,0,0,30069,0,30072,0,0,0,30073,0,0,0,0,30075,0, +0,0,0,0,0,30079,0,0,30080,0,0,0,0,0,30082,0,0,0,0,0,0,0,0,0,0,0,30084,30090,0,0, +30091,0,0,0,0,30098,30118,0,30119,0,30121,30130,0,0,0,0,0,0,0,0,0,0,0,0,0,30131, +30132,30133,0,0,0,0,0,0,30135,0,0,0,0,0,0,0,0,0,0,0,30136,0,0,30137,30138,0,0,0, +30139,30146,0,0,0,0,0,30147,0,0,30148,30151,0,0,0,30168,0,30172,30173,0,0,0,0,0, +0,0,0,30180,30181,0,30192,0,0,0,0,0,0,0,30194,30196,0,0,30199,0,0,30202,0,0,0,0, +30203,0,0,0,0,0,0,0,0,0,0,30213,0,0,0,30216,0,0,30217,0,0,0,30218,0,0,0,0,30219, +0,30220,0,30222,30227,0,0,0,0,0,30231,0,0,30233,30235,0,0,0,0,30238,0,30240, +30243,30245,0,30250,30252,0,0,0,30269,0,0,30271,30272,0,0,0,30278,30280,0,0, +30282,0,30284,0,30294,0,0,0,0,30295,30296,0,0,0,0,0,30298,30299,30302,30304, +30306,0,0,0,0,0,0,30316,30317,0,0,0,30318,0,0,0,30319,0,30320,30322,30326,0,0,0, +0,0,30327,0,30332,30348,30349,0,0,30356,0,0,0,0,0,0,0,0,30357,0,30358,0,30359, +30360,0,0,30365,30366,30378,0,0,0,0,30379,0,0,30381,0,30385,0,30388,30397,0,0,0, +30401,0,0,0,0,30403,0,0,0,0,0,30404,0,0,30405,0,30406,30408,0,30409,0,30410,0,0, +0,30417,0,0,30418,30419,0,30420,0,30424,0,0,0,30427,30430,30432,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,30433,0,0,0,0,0,0,0,30436,0,30437,30438,0,30441,30442,0,0, +0,30445,0,0,0,0,30452,30456,30457,0,0,0,30458,0,30464,0,0,0,0,0,0,30467,0,30469, +0,0,0,0,0,30477,0,0,30484,0,0,0,0,0,30485,0,0,0,0,0,30486,30487,30497,30498,0,0, +0,0,0,0,0,0,0,0,30505,0,30508,0,0,0,30509,30510,0,30514,30516,0,0,0,0,0,0,0,0,0, +0,0,30523,0,30524,0,30525,0,0,0,0,30537,0,0,30538,0,0,0,0,0,30553,0,0,30555, +30556,30558,30559,30560,0,0,30561,0,30562,0,0,0,0,0,0,0,0,30563,30570,30571,0, +30586,30587,0,0,30590,0,0,30594,0,0,0,0,30611,30612,30623,30634,0,0,30636,30640, +30655,30656,0,30657,0,0,30658,30669,0,30670,0,30676,30678,0,0,0,0,0,0,0,30679,0, +0,0,0,0,0,0,0,0,0,0,30695,0,0,30698,0,0,0,0,30700,0,0,0,0,30701,0,30702,30703,0, +0,0,0,30707,0,0,0,30709,0,0,30710,30719,30729,0,0,0,0,0,0,0,0,0,30731,0,0,30733, +0,0,0,30734,0,0,0,0,0,30736,30737,0,0,0,30740,0,0,0,30743,0,30746,0,30747,30748, +0,0,30751,30752,30753,0,0,0,30754,0,0,30760,0,0,0,0,0,0,0,30763,0,30764,0,0, +30766,0,30769,30770,30771,30774,30777,0,0,30779,30780,30781,0,0,0,0,30790,0,0,0, +30792,0,0,0,0,30810,0,0,0,0,0,0,0,30812,30819,0,0,30823,30824,0,30825,0,30827,0, +0,0,0,0,0,30828,0,0,30830,0,0,0,30834,0,30835,0,30837,30838,0,30845,0,0,0,0,0, +30846,30847,0,0,30849,0,30851,0,0,0,0,0,30852,30858,0,0,30859,0,30865,0,0,30866, +0,0,30868,0,0,30869,0,0,0,30881,30883,0,0,0,0,0,30889,0,30891,0,0,0,0,30894,0, +30895,0,30897,0,30898,0,0,0,30904,30906,0,30909,0,0,0,0,0,0,30910,0,0,0,30915, +30933,30942,0,0,0,0,30943,0,0,30945,0,0,0,0,0,0,30946,0,0,30947,0,0,30955,30956, +0,0,30960,0,0,30961,30962,30966,0,0,30969,30974,0,0,0,30976,0,0,30977,0,30978, +30982,0,0,0,0,0,0,0,30994,30995,30998,0,31000,0,0,31001,0,0,31003,31005,0,0, +31006,31011,0,0,31014,0,31016,0,0,0,0,31018,0,0,31020,31023,31024,31025,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,31027,31028,31029,0,0,0,0,0,0,31032,0,0,0,0,0,0,0,0,0,0,0, +31036,31037,31038,0,0,0,31041,31043,31045,0,31047,0,0,0,31048,0,31049,0,0,0, +31053,31054,31055,0,0,31063,0,0,0,0,0,31066,0,31068,31071,0,0,0,31072,31073,0,0, +0,0,31075,0,0,31076,0,0,0,31077,31079,0,31080,0,0,0,0,0,0,0,0,0,0,31087,0,31142, +0,31144,0,0,31145,31146,31147,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31149,0,31151,31152,0, +0,0,0,0,0,0,31162,31171,31174,31175,0,0,0,31176,0,0,0,0,0,0,0,31179,0,0,0,31186, +0,0,0,31192,31195,0,0,31196,0,0,0,0,0,0,0,0,31198,0,0,0,0,0,31199,0,0,0,31205,0, +0,0,0,31211,31215,0,0,0,0,31231,0,31232,0,0,0,0,0,0,0,0,0,0,31233,31236,31253,0, +31254,0,0,0,0,0,0,31255,0,0,31257,0,0,0,0,0,0,0,0,0,31258,31259,0,0,31260,0, +31261,0,0,0,0,0,31262,31263,0,0,31264,0,31266,0,31267,0,0,0,0,0,31281,0,31282,0, +31284,0,0,31285,31287,31288,0,0,31290,0,0,0,31292,31295,0,31299,0,31300,0,0,0,0, +0,31302,0,0,0,0,31303,0,0,0,0,0,0,31304,0,0,0,0,0,31305,31308,31309,31315,0, +31317,0,0,0,0,0,31323,0,31324,0,0,0,0,0,31325,31327,0,0,31331,0,0,0,0,0,31333,0, +0,0,0,0,31336,0,0,31337,0,0,0,0,0,0,31338,0,0,0,0,0,0,0,0,0,0,0,0,31339,0,0,0,0, +0,0,0,31342,0,0,0,0,31345,0,0,0,0,0,0,0,0,31347,0,0,0,0,0,0,31348,0,0,31350, +31351,0,31352,0,0,31354,0,0,0,0,31355,0,0,31356,0,0,0,0,0,0,0,0,0,0,31363,0, +31372,0,0,31373,0,0,0,0,0,0,0,0,0,31376,0,31388,0,31389,0,31392,0,31401,0,31405, +31407,31408,0,31409,0,0,0,0,0,0,31413,31415,0,0,0,31416,31418,0,0,0,0,0,0,31422, +31423,0,0,31424,0,31425,31432,0,0,0,0,0,0,0,0,0,31433,0,0,0,0,0,0,0,0,31434,0,0, +0,0,0,0,31435,0,0,0,0,31438,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31442,0,31444,0, +31448,0,0,31451,0,0,0,0,31452,0,31461,31465,0,0,31466,0,0,31467,0,0,31468,0,0,0, +31469,31473,0,31476,0,0,0,0,31489,31490,0,0,0,0,0,0,0,31492,31493,31494,0,0,0,0, +31501,31504,31505,0,0,0,0,0,0,0,0,0,31509,0,0,0,0,31510,0,0,31511,0,0,31513,0,0, +0,0,0,0,0,0,0,31514,0,31522,31536,31539,31540,0,31541,0,0,0,0,0,0,31546,31553, +31559,0,0,0,31560,31561,31562,0,0,31564,31567,0,31569,0,0,0,31570,0,0,0,0,31571, +0,0,0,0,0,0,31572,31574,31580,31581,0,0,31582,31584,31585,31586,31595,0,31596,0, +0,0,0,31597,0,31599,0,31600,31601,0,0,31603,31604,0,0,31608,31610,0,0,0,31611,0, +31615,0,0,0,0,31616,0,0,0,0,0,0,31617,0,0,0,0,0,31618,0,0,0,0,0,0,31621,0,0,0,0, +0,0,0,0,0,31622,31625,0,0,0,0,31627,0,31641,0,0,31642,0,0,31643,0,0,0,0,0,0,0,0, +0,31644,0,31646,0,0,0,0,31648,0,0,0,31652,0,0,0,31657,0,0,31676,0,0,0,0,0,0,0, +31689,31691,31692,0,31694,0,0,0,31696,0,31702,0,31703,0}; + +const BROTLI_MODEL("small") +DictWord kStaticDictionaryWords[BROTLI_ENC_STATIC_DICT_LUT_NUM_ITEMS] = { +{0,0,0},{8,0,1002},{136,0,1015},{4,0,683},{4,10,325},{138,10,125},{7,11,572},{9, +11,592},{11,11,680},{11,11,842},{11,11,924},{12,11,356},{12,11,550},{13,11,317}, +{13,11,370},{13,11,469},{13,11,471},{14,11,397},{18,11,69},{146,11,145},{134,0, +1265},{136,11,534},{134,0,1431},{11,0,138},{140,0,40},{4,0,155},{4,10,718},{7,0, +1689},{135,10,1216},{4,0,245},{5,0,151},{5,0,741},{6,0,1147},{7,0,498},{7,0,870} +,{7,0,1542},{12,0,213},{14,0,36},{14,0,391},{17,0,111},{18,0,6},{18,0,46},{18,0, +151},{19,0,36},{20,0,32},{20,0,56},{20,0,69},{20,0,102},{21,0,4},{22,0,8},{22,0, +10},{22,0,14},{150,0,31},{4,0,624},{135,0,1752},{5,10,124},{5,10,144},{6,10,548} +,{7,10,15},{7,10,153},{137,10,629},{6,0,503},{7,10,1531},{8,10,416},{9,0,586},{9 +,10,275},{10,10,100},{11,10,658},{11,10,979},{12,10,86},{13,0,468},{14,0,66},{14 +,10,207},{15,10,20},{15,10,25},{144,0,58},{5,0,603},{5,10,915},{6,10,1783},{7,0, +1212},{7,10,211},{7,10,1353},{9,0,565},{9,10,83},{10,10,376},{10,10,431},{11,10, +543},{12,10,664},{13,10,280},{13,10,428},{14,0,301},{14,10,128},{17,10,52},{145, +10,81},{4,0,492},{133,0,451},{135,0,835},{141,0,70},{132,0,539},{7,11,748},{139, +11,700},{7,11,1517},{11,11,597},{14,11,76},{14,11,335},{148,11,33},{6,0,113},{ +135,0,436},{4,10,338},{133,10,400},{136,0,718},{133,11,127},{133,11,418},{6,0, +1505},{6,11,198},{7,0,520},{11,10,892},{140,11,83},{4,10,221},{5,10,659},{5,10, +989},{7,10,697},{7,10,1211},{138,10,284},{135,0,1070},{5,11,276},{6,11,55},{135, +11,1369},{134,0,1515},{6,11,1752},{136,11,726},{138,10,507},{4,10,188},{7,10,805 +},{143,0,78},{5,10,884},{139,10,991},{133,11,764},{134,10,1653},{6,11,309},{7,11 +,331},{138,11,550},{135,11,1861},{132,11,348},{135,11,986},{135,11,1573},{12,0, +610},{13,0,431},{144,0,59},{9,11,799},{140,10,166},{134,0,1530},{132,0,750},{132 +,0,307},{133,0,964},{6,11,194},{7,11,133},{10,11,493},{10,11,570},{139,11,664},{ +5,11,24},{5,11,569},{6,11,3},{6,11,119},{6,11,143},{6,11,440},{7,11,295},{7,11, +599},{7,11,1686},{7,11,1854},{8,11,424},{9,11,43},{9,11,584},{9,11,760},{10,11, +148},{10,11,328},{11,11,159},{11,11,253},{11,11,506},{12,11,487},{12,11,531},{ +144,11,33},{136,10,760},{5,11,14},{5,11,892},{6,11,283},{7,11,234},{136,11,537}, +{135,11,1251},{4,11,126},{8,11,635},{147,11,34},{4,11,316},{135,11,1561},{6,0, +999},{6,0,1310},{137,11,861},{4,11,64},{5,11,352},{5,11,720},{6,11,368},{139,11, +359},{4,0,75},{5,0,180},{6,0,500},{7,0,58},{7,0,710},{8,10,770},{138,0,645},{133 +,0,649},{6,0,276},{7,0,282},{7,0,879},{7,0,924},{8,0,459},{9,0,599},{9,0,754},{ +11,0,574},{12,0,128},{12,0,494},{13,0,52},{13,0,301},{15,0,30},{143,0,132},{132, +0,200},{4,10,89},{5,10,489},{6,10,315},{7,10,553},{7,10,1745},{138,10,243},{135, +11,1050},{6,10,1658},{7,0,1621},{9,10,3},{10,10,154},{11,10,641},{13,10,85},{13, +10,201},{141,10,346},{6,11,175},{137,11,289},{5,11,432},{133,11,913},{6,0,225},{ +137,0,211},{7,0,718},{8,0,687},{139,0,374},{4,10,166},{133,10,505},{6,10,1670},{ +137,0,110},{8,0,58},{9,0,724},{11,0,809},{13,0,113},{145,0,72},{6,0,345},{7,0, +1247},{144,11,82},{5,11,931},{134,11,1698},{8,0,767},{8,0,803},{9,0,301},{137,0, +903},{139,0,203},{134,0,1154},{7,0,1949},{136,0,674},{134,0,259},{135,0,1275},{5 +,11,774},{6,11,1637},{6,11,1686},{134,11,1751},{134,0,1231},{7,10,445},{8,10,307 +},{8,10,704},{10,10,41},{10,10,439},{11,10,237},{11,10,622},{140,10,201},{136,0, +254},{6,11,260},{135,11,1484},{139,0,277},{135,10,1977},{4,10,189},{5,10,713},{6 +,11,573},{136,10,57},{138,10,371},{132,10,552},{134,11,344},{133,0,248},{6,11, +240},{9,0,800},{10,0,693},{11,0,482},{11,0,734},{139,0,789},{4,0,116},{4,11,292} +,{4,11,736},{5,0,95},{5,0,445},{5,11,871},{6,11,171},{6,11,1689},{7,0,1688},{7, +11,1324},{7,11,1944},{8,0,29},{9,0,272},{9,11,415},{9,11,580},{11,0,509},{11,0, +915},{14,11,230},{146,11,68},{7,0,490},{13,0,100},{143,0,75},{135,0,1641},{133,0 +,543},{7,11,209},{8,11,661},{10,11,42},{11,11,58},{12,11,58},{12,11,118},{141,11 +,32},{5,0,181},{6,11,63},{7,11,920},{136,0,41},{133,0,657},{133,11,793},{138,0, +709},{7,0,25},{8,0,202},{138,0,536},{5,11,665},{135,10,1788},{145,10,49},{9,0, +423},{140,0,89},{5,11,67},{6,11,62},{6,11,374},{135,11,1391},{8,0,113},{9,0,877} +,{9,11,790},{10,0,554},{11,0,83},{12,0,136},{12,11,47},{147,0,109},{138,10,661}, +{4,0,963},{7,10,1945},{10,0,927},{142,0,442},{133,0,976},{132,0,206},{4,11,391}, +{135,11,1169},{134,0,2002},{6,0,696},{134,0,1008},{134,0,1170},{132,11,271},{7,0 +,13},{8,0,226},{10,0,537},{11,0,570},{11,0,605},{11,0,799},{11,0,804},{12,0,85}, +{12,0,516},{12,0,623},{12,11,314},{13,0,112},{13,0,361},{14,0,77},{14,0,78},{17, +0,28},{147,0,110},{132,0,769},{134,0,1544},{4,0,551},{137,0,678},{5,10,84},{134, +10,163},{9,0,57},{9,0,459},{10,0,425},{11,0,119},{12,0,184},{12,0,371},{13,0,358 +},{145,0,51},{4,11,253},{5,0,188},{5,0,814},{5,10,410},{5,11,544},{7,11,300},{8, +0,10},{9,0,421},{9,0,729},{9,11,340},{10,0,609},{139,0,689},{134,0,624},{138,11, +321},{135,0,1941},{5,10,322},{8,10,186},{9,10,262},{10,10,187},{14,10,208},{146, +0,130},{5,11,53},{5,11,541},{6,11,94},{6,11,499},{7,11,230},{139,11,321},{133,10 +,227},{4,0,378},{4,11,920},{5,11,25},{5,11,790},{6,11,457},{135,11,853},{137,0, +269},{132,0,528},{134,0,1146},{7,10,1395},{8,10,486},{9,10,236},{9,10,878},{10, +10,218},{11,10,95},{19,10,17},{147,10,31},{7,10,2043},{8,10,672},{141,10,448},{ +134,0,1105},{134,0,1616},{134,11,1765},{140,11,163},{5,10,412},{133,11,822},{132 +,11,634},{6,0,656},{134,11,1730},{134,0,1940},{5,0,104},{6,0,173},{135,0,1631},{ +136,10,562},{6,11,36},{7,11,658},{8,11,454},{147,11,86},{5,0,457},{134,10,1771}, +{7,0,810},{8,0,138},{8,0,342},{9,0,84},{10,0,193},{11,0,883},{140,0,359},{7,10, +1190},{137,0,620},{137,10,132},{7,11,975},{137,11,789},{6,0,95},{6,0,1934},{136, +0,967},{141,11,335},{6,0,406},{10,0,409},{10,0,447},{11,0,44},{140,0,100},{4,10, +317},{135,10,1279},{132,0,477},{134,0,1268},{5,10,63},{5,10,509},{6,0,1941},{136 +,0,944},{132,0,629},{132,11,104},{4,0,246},{133,0,375},{4,10,288},{134,0,1636},{ +135,11,1614},{8,10,89},{8,10,620},{9,0,49},{10,0,774},{11,10,628},{12,10,322},{ +143,10,124},{4,0,282},{7,0,1034},{11,0,398},{11,0,634},{12,0,1},{12,0,79},{12,0, +544},{14,0,237},{17,0,10},{146,0,20},{132,0,824},{7,11,45},{9,11,542},{9,11,566} +,{138,11,728},{5,0,118},{5,0,499},{6,0,476},{6,0,665},{6,0,1176},{6,0,1196},{7,0 +,600},{7,0,888},{135,0,1096},{7,0,296},{7,0,596},{8,0,560},{8,0,586},{9,0,612},{ +11,0,304},{12,0,46},{13,0,89},{14,0,112},{145,0,122},{5,0,894},{6,0,1772},{9,0, +1009},{138,10,120},{5,11,533},{7,11,755},{138,11,780},{151,10,1},{6,0,1474},{7, +11,87},{142,11,288},{139,0,366},{137,10,461},{7,11,988},{7,11,1939},{9,11,64},{9 +,11,502},{12,11,7},{12,11,34},{13,11,12},{13,11,234},{147,11,77},{7,0,1599},{7,0 +,1723},{8,0,79},{8,0,106},{8,0,190},{8,0,302},{8,0,383},{8,0,713},{9,0,119},{9,0 +,233},{9,0,419},{9,0,471},{10,0,181},{10,0,406},{11,0,57},{11,0,85},{11,0,120},{ +11,0,177},{11,0,296},{11,0,382},{11,0,454},{11,0,758},{11,0,999},{12,0,27},{12,0 +,98},{12,0,131},{12,0,245},{12,0,312},{12,0,446},{12,0,454},{13,0,25},{13,0,98}, +{13,0,426},{13,0,508},{14,0,70},{14,0,163},{14,0,272},{14,0,277},{14,0,370},{15, +0,95},{15,0,138},{15,0,167},{17,0,38},{148,0,96},{135,10,1346},{10,0,200},{19,0, +2},{151,0,22},{135,11,141},{134,10,85},{134,0,1759},{138,0,372},{145,0,16},{4,11 +,619},{136,0,943},{139,11,88},{5,11,246},{8,11,189},{9,11,355},{9,11,512},{10,11 +,124},{10,11,453},{11,11,143},{11,11,416},{11,11,859},{141,11,341},{5,0,258},{ +134,0,719},{6,0,1798},{6,0,1839},{8,0,900},{10,0,874},{10,0,886},{12,0,698},{12, +0,732},{12,0,770},{16,0,106},{18,0,163},{18,0,170},{18,0,171},{152,0,20},{9,0, +707},{9,11,707},{11,0,326},{11,0,339},{11,11,326},{11,11,339},{12,0,423},{12,0, +502},{12,11,423},{12,11,502},{20,0,62},{148,11,62},{5,0,30},{7,0,495},{8,0,134}, +{9,0,788},{140,0,438},{133,11,678},{5,10,279},{6,10,235},{7,10,468},{8,10,446},{ +9,10,637},{10,10,717},{11,10,738},{140,10,514},{5,11,35},{6,11,287},{7,11,862},{ +7,11,1886},{138,11,179},{4,11,517},{7,0,1948},{135,0,2004},{5,10,17},{6,10,371}, +{137,10,528},{4,0,115},{5,0,669},{6,0,407},{8,0,311},{11,0,10},{141,0,5},{137,0, +381},{5,0,50},{6,0,439},{7,0,780},{135,0,1040},{136,11,667},{11,11,403},{146,11, +83},{5,0,1},{6,0,81},{138,0,520},{134,0,738},{5,0,482},{8,0,98},{9,0,172},{10,0, +360},{10,0,700},{10,0,822},{11,0,302},{11,0,778},{12,0,50},{12,0,127},{12,0,396} +,{13,0,62},{13,0,328},{14,0,122},{147,0,72},{9,11,157},{10,11,131},{140,11,72},{ +135,11,714},{135,11,539},{5,0,2},{6,0,512},{7,0,797},{7,0,1494},{8,0,253},{8,0, +589},{9,0,77},{10,0,1},{10,0,129},{10,0,225},{11,0,118},{11,0,226},{11,0,251},{ +11,0,430},{11,0,701},{11,0,974},{11,0,982},{12,0,64},{12,0,260},{12,0,488},{140, +0,690},{5,11,394},{7,11,367},{7,11,487},{7,11,857},{7,11,1713},{8,11,246},{9,11, +537},{10,11,165},{12,11,219},{140,11,561},{136,0,557},{5,10,779},{5,10,807},{6, +10,1655},{134,10,1676},{4,10,196},{5,10,558},{133,10,949},{11,11,827},{12,11,56} +,{14,11,34},{143,11,148},{137,0,347},{133,0,572},{134,0,832},{4,0,12},{7,0,504}, +{7,0,522},{7,0,809},{8,0,797},{141,0,88},{4,10,752},{133,11,449},{7,11,86},{8,11 +,103},{145,11,69},{7,11,2028},{138,11,641},{5,0,528},{6,11,1},{142,11,2},{134,0, +861},{4,10,227},{5,10,159},{5,10,409},{7,10,80},{10,0,294},{10,10,479},{12,10, +418},{14,10,50},{14,10,249},{142,10,295},{7,10,1470},{8,10,66},{8,10,137},{8,10, +761},{9,10,638},{11,10,80},{11,10,212},{11,10,368},{11,10,418},{12,10,8},{13,10, +15},{16,10,61},{17,10,59},{19,10,28},{148,10,84},{7,11,1148},{148,0,109},{6,11, +277},{7,11,1274},{7,11,1386},{7,11,1392},{12,11,129},{146,11,87},{6,11,187},{7, +11,39},{7,11,1203},{8,11,380},{8,11,542},{14,11,117},{149,11,28},{134,0,1187},{5 +,0,266},{9,0,290},{9,0,364},{10,0,293},{11,0,606},{142,0,45},{6,11,297},{7,11, +793},{139,11,938},{4,0,50},{6,0,594},{9,0,121},{10,0,49},{10,0,412},{139,0,834}, +{136,0,748},{7,11,464},{8,11,438},{11,11,105},{11,11,363},{12,11,231},{14,11,386 +},{15,11,102},{148,11,75},{132,0,466},{6,10,38},{7,10,1220},{8,10,185},{8,10,256 +},{9,10,22},{9,10,331},{10,10,738},{11,10,205},{11,10,540},{11,10,746},{13,0,399 +},{13,10,465},{14,0,337},{142,10,194},{9,0,378},{141,0,162},{137,0,519},{4,10, +159},{6,10,115},{7,10,252},{7,10,257},{7,10,1928},{8,10,69},{9,10,384},{10,10,91 +},{10,10,615},{12,10,375},{14,10,235},{18,10,117},{147,10,123},{5,10,911},{5,11, +604},{136,10,278},{132,0,667},{4,10,151},{7,10,1567},{8,0,351},{137,0,322},{134, +0,902},{133,10,990},{5,10,194},{7,10,1662},{9,10,90},{140,0,180},{4,0,869},{134, +0,1996},{134,0,813},{133,10,425},{137,11,761},{132,0,260},{133,10,971},{5,11,20} +,{6,11,298},{7,11,659},{7,11,1366},{137,11,219},{4,0,39},{5,0,36},{7,0,1843},{8, +0,407},{11,0,144},{140,0,523},{4,0,510},{10,0,587},{139,10,752},{7,0,29},{7,0,66 +},{7,0,1980},{10,0,487},{138,0,809},{9,10,662},{13,0,260},{14,0,82},{146,0,63},{ +5,10,72},{6,10,264},{7,10,21},{7,10,46},{7,10,2013},{8,10,215},{8,10,513},{10,10 +,266},{139,10,22},{134,0,570},{4,11,439},{6,0,565},{7,0,1667},{10,10,95},{11,10, +603},{12,11,242},{13,10,443},{14,10,160},{143,10,4},{134,0,1464},{134,10,431},{5 +,10,874},{6,10,1677},{9,0,372},{15,0,2},{15,10,0},{19,0,10},{147,0,18},{132,0, +787},{6,0,380},{7,10,939},{7,10,1172},{7,10,1671},{9,10,540},{10,10,696},{11,10, +265},{11,10,732},{11,10,928},{11,10,937},{12,0,399},{13,10,438},{149,0,19},{137, +0,200},{132,11,233},{132,0,516},{134,11,577},{132,0,844},{11,0,887},{14,0,365},{ +142,0,375},{132,11,482},{8,0,821},{140,0,44},{7,0,1655},{136,0,305},{5,10,682},{ +135,10,1887},{135,11,346},{132,10,696},{4,0,10},{7,0,917},{139,0,786},{5,11,795} +,{6,11,1741},{8,11,417},{137,11,782},{4,0,1016},{134,0,2031},{4,10,726},{5,0,684 +},{133,10,630},{6,0,1021},{134,0,1480},{8,10,802},{136,10,838},{134,0,27},{134,0 +,395},{135,11,622},{7,11,625},{135,11,1750},{4,11,203},{135,11,1936},{6,10,118}, +{7,10,215},{7,10,1521},{140,10,11},{132,0,813},{136,0,511},{7,10,615},{138,10, +251},{135,10,1044},{145,0,56},{133,10,225},{6,0,342},{6,0,496},{8,0,275},{137,0, +206},{4,0,909},{133,0,940},{132,0,891},{7,11,311},{9,11,308},{140,11,255},{4,10, +370},{5,10,756},{135,10,1326},{4,0,687},{134,0,1596},{134,0,1342},{6,10,1662},{7 +,10,48},{8,10,771},{10,10,116},{13,10,104},{14,10,105},{14,10,184},{15,10,168},{ +19,10,92},{148,10,68},{138,10,209},{4,11,400},{5,11,267},{135,11,232},{151,11,12 +},{6,0,41},{141,0,160},{141,11,314},{134,0,1718},{136,0,778},{142,11,261},{134,0 +,1610},{133,0,115},{132,0,294},{4,10,120},{142,0,314},{132,0,983},{5,0,193},{140 +,0,178},{138,10,429},{5,10,820},{135,10,931},{5,11,732},{6,0,994},{6,0,1051},{6, +0,1439},{135,0,174},{4,11,100},{7,11,679},{8,11,313},{138,10,199},{6,10,151},{6, +10,1675},{7,10,383},{151,10,10},{6,0,1796},{8,0,848},{8,0,867},{8,0,907},{10,0, +855},{140,0,703},{140,0,221},{4,0,122},{5,0,796},{5,0,952},{6,0,1660},{6,0,1671} +,{8,0,567},{9,0,687},{9,0,742},{10,0,686},{11,0,682},{11,0,909},{140,0,281},{5, +11,362},{5,11,443},{6,11,318},{7,11,1019},{139,11,623},{5,11,463},{136,11,296},{ +6,10,1624},{11,0,583},{12,10,422},{13,0,262},{142,10,360},{5,0,179},{7,0,1095},{ +135,0,1213},{4,10,43},{4,11,454},{5,10,344},{133,10,357},{4,0,66},{7,0,722},{135 +,0,904},{134,0,773},{5,10,888},{135,0,352},{5,11,48},{5,11,404},{6,11,557},{7,11 +,458},{8,11,597},{10,11,455},{10,11,606},{11,11,49},{11,11,548},{12,11,476},{13, +11,18},{141,11,450},{134,11,418},{132,10,711},{5,11,442},{135,11,1984},{141,0,35 +},{137,0,152},{134,0,1197},{135,11,1093},{137,11,203},{137,10,440},{10,0,592},{ +10,0,753},{12,0,317},{12,0,355},{12,0,465},{12,0,469},{12,0,560},{12,0,578},{141 +,0,243},{133,0,564},{134,0,797},{5,10,958},{133,10,987},{5,11,55},{7,11,376},{ +140,11,161},{133,11,450},{134,0,556},{134,0,819},{11,10,276},{142,10,293},{7,0, +544},{138,0,61},{4,10,65},{5,10,479},{5,10,1004},{7,10,1913},{8,0,719},{8,10,317 +},{9,10,302},{10,10,612},{141,10,22},{4,0,5},{4,10,261},{4,11,213},{5,0,498},{7, +10,510},{7,11,223},{8,0,637},{8,11,80},{137,0,521},{4,10,291},{5,0,927},{7,0,101 +},{7,11,381},{7,11,806},{7,11,820},{8,11,354},{8,11,437},{8,11,787},{9,10,515},{ +9,11,657},{10,11,58},{10,11,339},{10,11,749},{11,11,914},{12,10,152},{12,10,443} +,{12,11,162},{13,10,392},{13,11,75},{14,10,357},{14,11,106},{14,11,198},{14,11, +320},{14,11,413},{146,11,43},{6,0,1153},{7,0,1441},{136,11,747},{4,0,893},{5,0, +780},{133,0,893},{138,11,654},{133,11,692},{133,0,238},{134,11,191},{4,10,130},{ +135,10,843},{5,10,42},{5,10,879},{6,0,1296},{7,10,245},{7,10,324},{7,10,1532},{ +11,10,463},{11,10,472},{13,10,363},{144,10,52},{134,0,1729},{6,0,1999},{136,0, +969},{4,10,134},{133,10,372},{4,0,60},{7,0,941},{7,0,1800},{8,0,314},{9,0,700},{ +139,0,487},{134,0,1144},{6,11,162},{7,11,1960},{136,11,831},{132,11,706},{135,0, +1147},{138,11,426},{138,11,89},{7,0,1853},{138,0,437},{136,0,419},{135,10,1634}, +{133,0,828},{4,10,644},{5,0,806},{7,0,176},{7,0,178},{7,0,1240},{135,0,1976},{ +135,11,1877},{5,11,420},{135,11,1449},{4,0,51},{5,0,39},{6,0,4},{7,0,591},{7,0, +849},{7,0,951},{7,0,1613},{7,0,1760},{7,0,1988},{9,0,434},{10,0,754},{11,0,25},{ +139,0,37},{10,11,57},{138,11,277},{135,10,540},{132,11,204},{135,0,159},{139,11, +231},{133,0,902},{7,0,928},{7,11,366},{9,11,287},{12,11,199},{12,11,556},{140,11 +,577},{6,10,623},{136,10,789},{4,10,908},{5,10,359},{5,10,508},{6,10,1723},{7,10 +,343},{7,10,1996},{135,10,2026},{134,0,270},{4,10,341},{135,10,480},{5,11,356},{ +135,11,224},{11,11,588},{11,11,864},{11,11,968},{143,11,160},{132,0,556},{137,0, +801},{132,0,416},{142,0,372},{5,0,152},{5,0,197},{7,0,340},{7,0,867},{10,0,548}, +{10,0,581},{11,0,6},{12,0,3},{12,0,19},{14,0,110},{142,0,289},{139,0,369},{7,11, +630},{9,11,567},{11,11,150},{11,11,444},{141,11,119},{134,11,539},{7,10,1995},{8 +,10,299},{11,10,890},{140,10,674},{7,0,34},{7,0,190},{8,0,28},{8,0,141},{8,0,444 +},{8,0,811},{9,0,468},{11,0,334},{12,0,24},{12,0,386},{140,0,576},{133,0,757},{7 +,0,1553},{136,0,898},{133,0,721},{136,0,1012},{4,0,789},{5,0,647},{135,0,1102},{ +132,0,898},{4,10,238},{5,10,503},{6,10,179},{7,10,2003},{8,10,381},{8,10,473},{9 +,10,149},{10,0,183},{10,10,788},{15,10,45},{15,10,86},{20,10,110},{150,10,57},{4 +,10,121},{5,10,156},{5,10,349},{9,0,136},{10,10,605},{14,10,342},{147,0,107},{4, +11,235},{135,11,255},{4,11,194},{5,11,584},{6,11,384},{7,11,583},{10,11,761},{11 +,11,760},{139,11,851},{6,10,80},{6,10,1694},{7,10,173},{7,10,1974},{9,10,547},{ +10,10,730},{14,10,18},{150,10,39},{4,10,923},{134,10,1711},{5,0,277},{141,0,247} +,{132,0,435},{133,11,562},{134,0,1311},{5,11,191},{137,11,271},{132,10,595},{7, +11,1537},{14,11,96},{143,11,73},{5,0,437},{6,10,459},{7,0,502},{7,0,519},{7,0, +1122},{7,0,1751},{7,10,1753},{7,10,1805},{8,10,658},{9,10,1},{11,10,959},{13,10, +446},{142,0,211},{4,11,470},{5,11,473},{6,0,814},{6,11,153},{7,11,1503},{7,11, +1923},{10,11,701},{11,11,132},{11,11,168},{11,11,227},{11,11,320},{11,11,436},{ +11,11,525},{11,11,855},{12,11,41},{12,11,286},{13,11,103},{13,11,284},{14,11,255 +},{14,11,262},{15,11,117},{143,11,127},{5,0,265},{6,0,212},{135,0,28},{138,0,750 +},{133,11,327},{6,11,552},{7,11,1754},{137,11,604},{134,0,2012},{132,0,702},{5, +11,80},{6,11,405},{7,11,403},{7,11,1502},{7,11,1626},{8,11,456},{9,11,487},{9,11 +,853},{9,11,889},{10,11,309},{11,11,721},{11,11,994},{12,11,430},{141,11,165},{5 +,0,808},{135,0,2045},{5,0,166},{8,0,739},{140,0,511},{134,10,490},{4,11,453},{5, +11,887},{6,11,535},{8,11,6},{136,11,543},{4,0,119},{5,0,170},{5,0,447},{7,0,1708 +},{7,0,1889},{9,0,357},{9,0,719},{12,0,486},{140,0,596},{137,0,500},{7,10,250},{ +136,10,507},{132,10,158},{6,0,809},{134,0,1500},{4,10,140},{7,10,362},{8,10,209} +,{9,0,327},{9,10,10},{9,10,503},{9,10,614},{10,10,689},{11,0,350},{11,0,831},{11 +,10,327},{11,10,725},{12,10,252},{12,10,583},{13,0,352},{13,10,192},{14,10,269}, +{14,10,356},{148,10,50},{135,11,741},{4,0,450},{7,0,1158},{19,10,1},{19,10,26},{ +150,10,9},{6,0,597},{135,0,1318},{134,0,1602},{6,10,228},{7,10,1341},{9,10,408}, +{138,10,343},{7,0,1375},{7,0,1466},{138,0,331},{132,0,754},{132,10,557},{5,11, +101},{6,11,88},{6,11,543},{7,11,1677},{9,11,100},{10,11,677},{14,11,169},{14,11, +302},{14,11,313},{15,11,48},{143,11,84},{134,0,1368},{4,11,310},{9,11,795},{10, +11,733},{11,11,451},{12,11,249},{14,11,115},{14,11,286},{143,11,100},{132,10,548 +},{7,10,197},{8,10,142},{8,10,325},{9,10,150},{9,10,596},{10,0,557},{10,10,353}, +{11,10,74},{11,10,315},{12,10,662},{12,10,681},{14,10,423},{143,10,141},{133,11, +587},{5,0,850},{136,0,799},{10,0,908},{12,0,701},{12,0,757},{142,0,466},{4,0,62} +,{5,0,275},{6,10,399},{6,10,579},{7,10,692},{7,10,846},{7,10,1015},{7,10,1799},{ +8,10,403},{9,10,394},{10,10,133},{12,10,4},{12,10,297},{12,10,452},{16,10,81},{ +18,0,19},{18,10,25},{21,10,14},{22,10,12},{151,10,18},{7,10,1546},{11,10,299},{ +12,0,459},{142,10,407},{132,10,177},{132,11,498},{7,11,217},{8,11,140},{138,11, +610},{5,10,411},{135,10,653},{134,0,1802},{7,10,439},{10,10,727},{11,10,260},{ +139,10,684},{133,11,905},{11,11,580},{142,11,201},{134,0,1397},{5,10,208},{7,10, +753},{135,10,1528},{7,0,238},{7,0,2033},{8,0,120},{8,0,188},{8,0,659},{9,0,598}, +{10,0,466},{12,0,342},{12,0,588},{13,0,503},{14,0,246},{143,0,92},{135,11,1041}, +{4,11,456},{7,11,105},{7,11,358},{7,11,1637},{8,11,643},{139,11,483},{6,0,1318}, +{134,0,1324},{4,0,201},{5,10,242},{7,0,1744},{8,0,602},{11,0,247},{11,0,826},{ +145,0,65},{8,0,164},{146,0,62},{133,10,953},{139,10,802},{133,0,615},{7,11,1566} +,{8,11,269},{9,11,212},{9,11,718},{14,11,15},{14,11,132},{142,11,227},{133,10, +290},{132,10,380},{5,10,52},{7,10,277},{9,10,368},{139,10,791},{135,0,1243},{133 +,11,539},{11,11,919},{141,11,409},{136,0,968},{133,11,470},{134,0,882},{132,0, +907},{5,0,100},{10,0,329},{12,0,416},{149,0,29},{10,10,138},{139,10,476},{5,10, +725},{5,10,727},{6,11,91},{7,10,1811},{135,11,435},{4,11,16},{5,11,316},{5,11, +842},{6,11,370},{6,11,1778},{8,11,166},{11,11,812},{12,11,206},{12,11,351},{14, +11,418},{16,11,15},{16,11,34},{18,11,3},{19,11,3},{19,11,7},{20,11,4},{149,11,21 +},{132,0,176},{5,0,636},{5,0,998},{7,0,9},{7,0,1508},{8,0,26},{9,0,317},{9,0,358 +},{10,0,210},{10,0,292},{10,0,533},{11,0,555},{12,0,526},{12,0,607},{13,0,263},{ +13,0,459},{142,0,271},{4,10,38},{6,0,256},{7,10,307},{7,10,999},{7,10,1481},{7, +10,1732},{7,10,1738},{8,0,265},{9,10,414},{11,10,316},{12,10,52},{13,10,420},{ +147,10,100},{135,10,1296},{4,11,611},{133,11,606},{4,0,643},{142,11,21},{133,11, +715},{133,10,723},{6,0,610},{135,11,597},{10,0,127},{141,0,27},{6,0,1995},{6,0, +2001},{8,0,119},{136,0,973},{4,11,149},{138,11,368},{4,11,154},{5,10,109},{6,10, +1784},{7,10,1895},{7,11,1134},{8,11,105},{12,0,522},{12,10,296},{140,10,302},{4, +11,31},{6,11,429},{7,11,962},{9,11,458},{139,11,691},{4,11,312},{5,10,216},{7,10 +,1879},{9,10,141},{9,10,270},{9,10,679},{10,0,553},{10,10,159},{11,0,876},{11,10 +,197},{12,10,538},{12,10,559},{13,0,193},{13,0,423},{14,0,166},{14,10,144},{14, +10,167},{15,10,67},{147,0,84},{134,0,1582},{7,0,1578},{135,11,1578},{137,10,81}, +{132,11,236},{134,10,391},{134,0,795},{7,10,322},{136,10,249},{5,11,836},{5,11, +857},{6,11,1680},{7,11,59},{147,11,53},{135,0,432},{10,11,68},{139,11,494},{4,11 +,81},{139,11,867},{7,0,126},{136,0,84},{142,11,280},{5,11,282},{8,11,650},{9,11, +295},{9,11,907},{138,11,443},{136,0,790},{5,10,632},{138,10,526},{6,0,64},{12,0, +377},{13,0,309},{14,0,141},{14,0,429},{14,11,141},{142,11,429},{134,0,1529},{6,0 +,321},{7,0,1857},{7,10,948},{7,10,1042},{8,10,235},{8,10,461},{9,0,530},{9,10, +453},{10,10,354},{17,10,77},{147,0,99},{7,0,1104},{11,0,269},{11,0,539},{11,0, +627},{11,0,706},{11,0,975},{12,0,248},{12,0,434},{12,0,600},{12,0,622},{13,0,297 +},{13,0,485},{14,0,69},{14,0,409},{143,0,108},{4,10,362},{7,10,52},{7,10,303},{ +10,11,70},{12,11,26},{14,11,17},{14,11,178},{15,11,34},{149,11,12},{11,0,977},{ +141,0,507},{9,0,34},{139,0,484},{5,10,196},{6,10,486},{7,10,212},{8,10,309},{136 +,10,346},{6,0,1700},{7,0,26},{7,0,293},{7,0,382},{7,0,1026},{7,0,1087},{7,0,2027 +},{7,10,1912},{8,0,24},{8,0,114},{8,0,252},{8,0,727},{8,0,729},{9,0,30},{9,0,199 +},{9,0,231},{9,0,251},{9,0,334},{9,0,361},{9,0,712},{10,0,55},{10,0,60},{10,0, +232},{10,0,332},{10,0,384},{10,0,396},{10,0,504},{10,0,542},{10,0,652},{11,0,20} +,{11,0,48},{11,0,207},{11,0,291},{11,0,298},{11,0,342},{11,0,365},{11,0,394},{11 +,0,620},{11,0,705},{11,0,1017},{12,0,123},{12,0,340},{12,0,406},{12,0,643},{13,0 +,61},{13,0,269},{13,0,311},{13,0,319},{13,0,486},{14,0,234},{15,0,62},{15,0,85}, +{16,0,71},{18,0,119},{148,0,105},{4,11,71},{5,11,376},{7,11,119},{138,11,665},{4 +,10,686},{8,11,55},{10,0,918},{138,0,926},{138,10,625},{136,10,706},{132,11,479} +,{4,10,30},{133,10,43},{6,0,379},{7,0,270},{7,11,607},{8,0,176},{8,0,183},{8,11, +99},{9,0,432},{9,0,661},{12,0,247},{12,0,617},{18,0,125},{152,11,4},{5,0,792},{ +133,0,900},{4,11,612},{133,11,561},{4,10,220},{4,11,41},{5,11,74},{7,10,1535},{7 +,11,1627},{11,11,871},{140,11,619},{135,0,1920},{7,11,94},{11,11,329},{11,11,965 +},{12,11,241},{14,11,354},{15,11,22},{148,11,63},{9,11,209},{137,11,300},{134,0, +771},{135,0,1979},{4,0,901},{133,0,776},{142,0,254},{133,11,98},{9,11,16},{141, +11,386},{133,11,984},{4,11,182},{6,11,205},{135,11,220},{7,10,1725},{7,10,1774}, +{138,10,393},{5,10,263},{134,10,414},{4,11,42},{9,11,205},{9,11,786},{138,11,659 +},{14,0,140},{148,0,41},{6,10,178},{6,10,1750},{6,11,289},{7,11,1670},{8,0,440}, +{9,10,690},{10,0,359},{10,10,155},{10,10,373},{11,10,698},{12,11,57},{13,10,155} +,{20,10,93},{151,11,4},{4,0,37},{5,0,334},{7,0,1253},{151,11,25},{4,0,508},{4,11 +,635},{5,10,97},{137,10,393},{139,11,533},{4,0,640},{133,0,513},{134,10,1639},{ +132,11,371},{4,11,272},{7,11,836},{7,11,1651},{145,11,89},{5,11,825},{6,11,444}, +{6,11,1640},{136,11,308},{4,10,191},{7,10,934},{8,10,647},{145,10,97},{12,0,246} +,{15,0,162},{19,0,64},{20,0,8},{20,0,95},{22,0,24},{152,0,17},{4,0,533},{5,10, +165},{9,10,346},{138,10,655},{5,11,737},{139,10,885},{133,10,877},{8,10,128},{ +139,10,179},{137,11,307},{140,0,752},{133,0,920},{135,0,1048},{5,0,153},{6,0,580 +},{6,10,1663},{7,10,132},{7,10,1154},{7,10,1415},{7,10,1507},{12,10,493},{15,10, +105},{151,10,15},{5,10,459},{7,10,1073},{8,10,241},{136,10,334},{138,0,391},{135 +,0,1952},{133,11,525},{8,11,641},{11,11,388},{140,11,580},{142,0,126},{134,0,640 +},{132,0,483},{6,10,324},{6,10,520},{7,0,1616},{7,10,338},{7,10,1729},{8,10,228} +,{9,0,69},{139,10,750},{5,11,493},{134,11,528},{135,0,734},{4,11,174},{135,11, +911},{138,0,480},{9,0,495},{146,0,104},{135,10,705},{4,10,73},{6,10,612},{7,10, +927},{7,10,1330},{7,10,1822},{8,10,217},{9,0,472},{9,10,765},{9,10,766},{10,10, +408},{11,10,51},{11,10,793},{12,10,266},{15,10,158},{20,10,89},{150,10,32},{7,11 +,548},{137,11,58},{4,11,32},{5,11,215},{6,11,269},{7,11,1782},{7,11,1892},{10,11 +,16},{11,11,822},{11,11,954},{141,11,481},{132,0,874},{5,10,389},{8,10,636},{137 +,0,229},{7,11,1749},{136,11,477},{134,0,948},{5,11,308},{135,11,1088},{4,0,748}, +{139,0,1009},{136,10,21},{6,0,555},{135,0,485},{5,11,126},{8,11,297},{9,11,366}, +{9,11,445},{12,11,53},{12,11,374},{141,11,492},{7,11,1551},{139,11,361},{136,0, +193},{136,0,472},{8,0,653},{13,0,93},{147,0,14},{132,0,984},{132,11,175},{4,11, +685},{5,0,172},{134,0,1971},{149,11,8},{133,11,797},{5,10,189},{7,10,442},{7,10, +443},{8,10,281},{12,10,174},{13,0,83},{141,10,261},{134,0,1568},{133,11,565},{ +139,0,384},{133,0,260},{6,10,2},{7,0,758},{7,0,880},{7,0,1359},{7,10,1262},{7,10 +,1737},{8,10,22},{8,10,270},{8,10,612},{9,0,164},{9,0,167},{9,10,312},{9,10,436} +,{10,0,156},{10,0,588},{10,10,311},{10,10,623},{11,10,72},{11,10,330},{11,10,455 +},{12,0,101},{12,10,321},{12,10,504},{12,10,530},{12,10,543},{13,10,17},{13,10, +156},{13,10,334},{14,0,48},{15,0,70},{17,10,60},{148,10,64},{4,11,252},{7,11, +1068},{10,11,434},{11,11,228},{11,11,426},{13,11,231},{18,11,106},{148,11,87},{7 +,10,354},{10,10,410},{139,10,815},{6,0,367},{7,10,670},{7,10,1327},{8,10,411},{8 +,10,435},{9,10,653},{9,10,740},{10,10,385},{11,10,222},{11,10,324},{11,10,829},{ +140,10,611},{6,10,166},{7,0,1174},{135,10,374},{146,0,121},{132,0,828},{5,11,231 +},{138,11,509},{7,11,601},{9,11,277},{9,11,674},{10,11,178},{10,11,257},{10,11, +418},{11,11,531},{11,11,544},{11,11,585},{12,11,113},{12,11,475},{13,11,99},{142 +,11,428},{134,0,1541},{135,11,1779},{5,0,343},{134,10,398},{135,10,50},{135,11, +1683},{4,0,440},{7,0,57},{8,0,167},{8,0,375},{9,0,82},{9,0,561},{9,0,744},{9,11, +744},{138,0,620},{134,0,926},{6,10,517},{7,10,1159},{10,10,621},{139,10,192},{ +137,0,827},{8,0,194},{136,0,756},{10,10,223},{139,10,645},{7,10,64},{136,10,245} +,{4,11,399},{5,11,119},{5,11,494},{7,11,751},{137,11,556},{132,0,808},{135,0,22} +,{7,10,1763},{140,10,310},{5,0,639},{6,11,584},{7,0,1249},{139,0,896},{134,0, +1614},{135,0,860},{135,11,1121},{5,10,129},{6,10,61},{135,10,947},{4,0,102},{7,0 +,815},{7,0,1699},{139,0,964},{13,10,505},{141,10,506},{139,10,1000},{132,11,679} +,{132,0,899},{132,0,569},{5,11,694},{137,11,714},{136,0,795},{6,0,2045},{139,11, +7},{6,0,52},{9,0,104},{9,0,559},{12,0,308},{147,0,87},{4,0,301},{132,0,604},{133 +,10,637},{136,0,779},{5,11,143},{5,11,769},{6,11,1760},{7,11,682},{7,11,1992},{ +136,11,736},{137,10,590},{147,0,32},{137,11,527},{5,10,280},{135,10,1226},{134,0 +,494},{6,0,677},{6,0,682},{134,0,1044},{133,10,281},{135,10,1064},{5,11,860},{ +135,0,508},{6,11,422},{7,11,0},{7,11,1544},{9,11,577},{11,11,990},{12,11,141},{ +12,11,453},{13,11,47},{141,11,266},{134,0,1014},{5,11,515},{137,11,131},{134,0, +957},{132,11,646},{6,0,310},{7,0,1849},{8,0,72},{8,0,272},{8,0,431},{9,0,12},{9, +0,376},{10,0,563},{10,0,630},{10,0,796},{10,0,810},{11,0,367},{11,0,599},{11,0, +686},{140,0,672},{4,11,396},{7,0,570},{7,10,120},{7,11,728},{8,10,489},{9,10,319 +},{9,11,117},{10,10,820},{11,10,1004},{12,10,379},{12,10,679},{13,10,117},{13,10 +,412},{13,11,202},{14,10,25},{15,10,52},{15,10,161},{16,10,47},{20,11,51},{149, +10,2},{6,11,121},{6,11,124},{6,11,357},{7,11,1138},{7,11,1295},{8,11,162},{139, +11,655},{4,10,937},{5,10,801},{8,0,449},{136,11,449},{139,11,958},{6,0,181},{7,0 +,537},{8,0,64},{9,0,127},{10,0,496},{12,0,510},{141,0,384},{138,11,253},{4,0,244 +},{135,0,233},{133,11,237},{132,10,365},{6,0,1650},{10,0,702},{139,0,245},{5,10, +7},{139,10,774},{13,0,463},{13,11,463},{20,0,49},{148,11,49},{4,10,734},{5,10, +662},{134,10,430},{4,10,746},{135,10,1090},{5,10,360},{136,10,237},{137,0,338},{ +143,11,10},{7,11,571},{138,11,366},{134,0,1279},{9,11,513},{10,11,22},{10,11,39} +,{12,11,122},{140,11,187},{133,0,896},{146,0,178},{134,0,695},{137,0,808},{134, +11,587},{7,11,107},{7,11,838},{8,11,550},{138,11,401},{7,0,1117},{136,0,539},{4, +10,277},{5,10,608},{6,10,493},{7,10,457},{140,10,384},{133,11,768},{7,10,27},{7, +10,316},{140,0,257},{140,0,1003},{4,0,207},{5,0,586},{5,0,676},{5,10,552},{6,0, +448},{8,0,244},{11,0,1},{13,0,3},{16,0,54},{17,0,4},{146,0,13},{4,10,401},{137, +10,264},{5,0,516},{7,0,1883},{135,11,1883},{4,11,894},{140,0,960},{5,0,4},{5,0, +810},{6,0,13},{6,0,538},{6,0,1690},{6,0,1726},{7,0,499},{7,0,1819},{8,0,148},{8, +0,696},{8,0,791},{12,0,125},{143,0,9},{135,0,1268},{9,10,543},{10,10,524},{11,0, +30},{12,10,524},{14,0,315},{16,10,18},{20,10,26},{148,10,65},{4,10,205},{5,10, +623},{6,0,748},{7,10,104},{136,10,519},{11,0,542},{139,0,852},{140,0,6},{132,0, +848},{7,0,1385},{7,10,579},{9,10,41},{9,10,244},{9,10,669},{10,10,5},{11,0,582}, +{11,0,650},{11,0,901},{11,0,949},{11,10,861},{11,10,951},{11,10,980},{12,0,232}, +{12,0,236},{13,0,413},{13,0,501},{146,0,116},{4,0,945},{6,0,1811},{6,0,1845},{6, +0,1853},{6,0,1858},{8,0,862},{12,0,782},{12,0,788},{18,0,160},{148,0,117},{132, +10,717},{4,0,925},{5,0,803},{8,0,698},{138,0,828},{134,0,1416},{132,0,610},{139, +0,992},{6,0,878},{134,0,1477},{135,0,1847},{138,11,531},{137,11,539},{134,11,272 +},{133,0,383},{134,0,1404},{132,10,489},{4,11,9},{5,11,128},{7,11,368},{11,11, +480},{148,11,3},{136,0,986},{9,0,660},{138,0,347},{135,10,892},{136,11,682},{7,0 +,572},{9,0,592},{11,0,680},{12,0,356},{140,0,550},{7,0,1411},{138,11,527},{4,11, +2},{7,11,545},{135,11,894},{137,10,473},{7,10,819},{7,11,481},{9,10,26},{9,10, +392},{9,11,792},{10,10,152},{10,10,226},{11,0,64},{12,10,276},{12,10,426},{12,10 +,589},{13,10,460},{15,10,97},{19,10,48},{148,10,104},{135,10,51},{136,11,445},{ +136,11,646},{135,0,606},{132,10,674},{6,0,1829},{134,0,1830},{132,10,770},{5,10, +79},{7,10,1027},{7,10,1477},{139,10,52},{5,11,530},{142,11,113},{134,10,1666},{7 +,0,748},{139,0,700},{134,10,195},{133,10,789},{4,10,251},{4,10,688},{7,10,513},{ +7,10,1284},{9,0,87},{138,0,365},{136,11,111},{133,0,127},{6,0,198},{140,0,83},{ +133,11,556},{133,10,889},{4,10,160},{5,10,330},{7,10,1434},{136,10,174},{5,0,276 +},{6,0,55},{7,0,1369},{138,0,864},{8,11,16},{140,11,568},{6,0,1752},{136,0,726}, +{135,0,1066},{133,0,764},{6,11,186},{137,11,426},{11,0,683},{139,11,683},{6,0, +309},{7,0,331},{138,0,550},{133,10,374},{6,0,1212},{6,0,1852},{7,0,1062},{8,0, +874},{8,0,882},{138,0,936},{132,11,585},{134,0,1364},{5,10,731},{135,0,986},{6,0 +,723},{6,0,1408},{138,0,381},{135,0,1573},{134,0,1025},{4,10,626},{5,10,642},{6, +10,425},{10,10,202},{139,10,141},{4,11,93},{5,11,252},{6,11,229},{7,11,291},{9, +11,550},{139,11,644},{137,11,749},{137,11,162},{132,11,381},{135,0,1559},{6,0, +194},{7,0,133},{10,0,493},{10,0,570},{139,0,664},{5,0,24},{5,0,569},{6,0,3},{6,0 +,119},{6,0,143},{6,0,440},{7,0,295},{7,0,599},{7,0,1686},{7,0,1854},{8,0,424},{9 +,0,43},{9,0,584},{9,0,760},{10,0,148},{10,0,328},{11,0,159},{11,0,253},{11,0,506 +},{12,0,487},{140,0,531},{6,0,661},{134,0,1517},{136,10,835},{151,10,17},{5,0,14 +},{5,0,892},{6,0,283},{7,0,234},{136,0,537},{139,0,541},{4,0,126},{8,0,635},{147 +,0,34},{4,0,316},{4,0,495},{135,0,1561},{4,11,187},{5,11,184},{5,11,690},{7,11, +1869},{138,11,756},{139,11,783},{4,0,998},{137,0,861},{136,0,1009},{139,11,292}, +{5,11,21},{6,11,77},{6,11,157},{7,11,974},{7,11,1301},{7,11,1339},{7,11,1490},{7 +,11,1873},{137,11,628},{7,11,1283},{9,11,227},{9,11,499},{10,11,341},{11,11,325} +,{11,11,408},{14,11,180},{15,11,144},{18,11,47},{147,11,49},{4,0,64},{5,0,352},{ +5,0,720},{6,0,368},{139,0,359},{5,10,384},{8,10,455},{140,10,48},{5,10,264},{134 +,10,184},{7,0,1577},{10,0,304},{10,0,549},{12,0,365},{13,0,220},{13,0,240},{142, +0,33},{134,0,1107},{134,0,929},{135,0,1142},{6,0,175},{137,0,289},{5,0,432},{133 +,0,913},{5,10,633},{6,0,279},{7,0,219},{135,10,1323},{7,0,785},{7,10,359},{8,10, +243},{140,10,175},{139,0,595},{132,10,105},{8,11,398},{9,11,681},{139,11,632},{ +140,0,80},{5,0,931},{134,0,1698},{142,11,241},{134,11,20},{134,0,1323},{11,0,526 +},{11,0,939},{141,0,290},{5,0,774},{6,0,780},{6,0,1637},{6,0,1686},{6,0,1751},{8 +,0,559},{141,0,109},{141,0,127},{7,0,1167},{7,11,709},{11,0,934},{13,0,391},{145 +,0,76},{135,0,963},{6,0,260},{135,0,1484},{134,0,573},{4,10,758},{139,11,941},{ +135,10,1649},{145,11,36},{4,0,292},{137,0,580},{4,0,736},{5,0,871},{6,0,1689},{ +135,0,1944},{7,11,945},{11,11,713},{139,11,744},{134,0,1164},{135,11,937},{6,0, +1922},{7,11,1652},{9,0,982},{15,0,173},{15,0,178},{15,0,200},{18,0,189},{18,0, +207},{149,0,47},{7,0,1695},{139,10,128},{6,0,63},{135,0,920},{133,0,793},{143,11 +,134},{133,10,918},{5,0,67},{6,0,62},{6,0,374},{135,0,1391},{4,11,579},{5,11,226 +},{5,11,323},{7,11,960},{9,0,790},{140,0,47},{10,11,784},{141,11,191},{4,0,391}, +{135,0,1169},{137,0,443},{13,11,232},{146,11,35},{132,10,340},{132,0,271},{137, +11,313},{5,11,973},{137,11,659},{134,0,1140},{6,11,135},{135,11,1176},{4,0,253}, +{5,0,544},{7,0,300},{137,0,340},{5,10,985},{7,0,897},{7,10,509},{145,10,96},{138 +,11,735},{135,10,1919},{138,0,890},{5,0,818},{134,0,1122},{5,0,53},{5,0,541},{6, +0,94},{6,0,499},{7,0,230},{139,0,321},{4,0,920},{5,0,25},{5,0,790},{6,0,457},{7, +0,853},{8,0,788},{142,11,31},{132,10,247},{135,11,314},{132,0,468},{6,10,337},{7 +,0,243},{7,10,494},{8,10,27},{8,10,599},{138,10,153},{4,10,184},{5,10,390},{7,10 +,618},{7,10,1456},{139,10,710},{134,0,870},{134,0,1238},{134,0,1765},{10,0,853}, +{10,0,943},{14,0,437},{14,0,439},{14,0,443},{14,0,446},{14,0,452},{14,0,469},{14 +,0,471},{14,0,473},{16,0,93},{16,0,102},{16,0,110},{148,0,121},{4,0,605},{7,0, +518},{7,0,1282},{7,0,1918},{10,0,180},{139,0,218},{133,0,822},{4,0,634},{11,0, +916},{142,0,419},{6,11,281},{7,11,6},{8,11,282},{8,11,480},{8,11,499},{9,11,198} +,{10,11,143},{10,11,169},{10,11,211},{10,11,417},{10,11,574},{11,11,147},{11,11, +395},{12,11,75},{12,11,407},{12,11,608},{13,11,500},{142,11,251},{134,0,898},{6, +0,36},{7,0,658},{8,0,454},{150,11,48},{133,11,674},{135,11,1776},{4,11,419},{10, +10,227},{11,10,497},{11,10,709},{140,10,415},{6,10,360},{7,10,1664},{136,10,478} +,{137,0,806},{12,11,508},{14,11,102},{14,11,226},{144,11,57},{135,11,1123},{4,11 +,138},{7,11,1012},{7,11,1280},{137,11,76},{5,11,29},{140,11,638},{136,10,699},{ +134,0,1326},{132,0,104},{135,11,735},{132,10,739},{134,0,1331},{7,0,260},{135,11 +,260},{135,11,1063},{7,0,45},{9,0,542},{9,0,566},{9,10,869},{138,0,728},{4,10,67 +},{5,10,422},{7,10,1037},{7,10,1289},{7,10,1555},{9,10,741},{145,10,108},{139,0, +263},{134,0,1516},{14,0,146},{15,0,42},{16,0,23},{17,0,86},{146,0,17},{138,0,468 +},{136,0,1005},{4,11,17},{5,11,23},{7,11,995},{11,11,383},{11,11,437},{12,11,460 +},{140,11,532},{7,0,87},{142,0,288},{138,10,96},{135,11,626},{144,10,26},{7,0, +988},{7,0,1939},{9,0,64},{9,0,502},{12,0,22},{12,0,34},{13,0,12},{13,0,234},{147 +,0,77},{8,10,203},{11,10,823},{11,10,846},{12,10,482},{13,0,133},{13,10,277},{13 +,10,302},{13,10,464},{14,10,205},{142,10,221},{4,10,449},{133,10,718},{135,0,141 +},{6,0,1842},{136,0,872},{8,11,70},{12,11,171},{141,11,272},{4,10,355},{6,10,311 +},{9,10,256},{138,10,404},{132,0,619},{137,0,261},{10,10,758},{10,11,233},{139, +11,76},{5,0,246},{8,0,189},{9,0,355},{9,0,512},{10,0,124},{10,0,453},{11,0,143}, +{11,0,416},{11,0,859},{141,0,341},{134,11,442},{133,10,827},{5,10,64},{140,10, +581},{4,10,442},{7,10,1047},{7,10,1352},{135,10,1643},{134,11,1709},{5,0,678},{5 +,10,977},{6,0,305},{7,0,775},{135,0,1065},{11,11,69},{12,11,105},{12,11,117},{13 +,11,213},{14,11,13},{14,11,62},{14,11,177},{14,11,421},{15,11,19},{146,11,141},{ +137,11,309},{5,0,35},{7,0,862},{7,0,1886},{138,0,179},{136,0,285},{132,0,517},{7 +,11,976},{9,11,146},{10,11,206},{10,11,596},{13,11,218},{142,11,153},{132,10,254 +},{4,10,275},{6,0,214},{7,10,1219},{12,0,540},{140,10,376},{8,0,667},{11,0,403}, +{146,0,83},{10,11,648},{11,11,671},{12,0,74},{143,11,46},{135,0,125},{134,10, +1753},{133,0,761},{4,11,518},{6,0,912},{6,10,369},{6,10,502},{7,10,1036},{7,11, +1136},{8,10,348},{9,10,452},{10,10,26},{11,10,224},{11,10,387},{11,10,772},{12, +10,95},{12,10,629},{13,10,195},{13,10,207},{13,10,241},{14,10,260},{14,10,270},{ +143,10,140},{10,0,131},{140,0,72},{132,10,269},{5,10,480},{7,10,532},{7,10,1197} +,{7,10,1358},{8,10,291},{11,10,349},{142,10,396},{8,11,689},{137,11,863},{8,0, +333},{138,0,182},{4,11,18},{7,11,145},{7,11,444},{7,11,1278},{8,11,49},{8,11,400 +},{9,11,71},{9,11,250},{10,11,459},{12,11,160},{144,11,24},{14,11,35},{142,11, +191},{135,11,1864},{135,0,1338},{148,10,15},{14,0,94},{15,0,65},{16,0,4},{16,0, +77},{16,0,80},{145,0,5},{12,11,82},{143,11,36},{133,11,1010},{133,0,449},{133,0, +646},{7,0,86},{7,10,657},{136,0,103},{7,0,2028},{138,0,641},{136,10,533},{134,0, +1},{139,11,970},{5,11,87},{7,11,313},{7,11,1103},{10,11,112},{10,11,582},{11,11, +389},{11,11,813},{12,11,385},{13,11,286},{14,11,124},{146,11,108},{4,11,267},{ +134,0,869},{6,0,277},{7,0,1274},{7,0,1386},{146,0,87},{6,0,187},{7,0,39},{7,0, +1203},{8,0,380},{14,0,117},{149,0,28},{4,10,211},{4,10,332},{5,10,335},{6,10,238 +},{7,10,269},{7,10,811},{7,10,1797},{8,10,836},{9,10,507},{141,10,242},{4,0,785} +,{5,0,368},{6,0,297},{7,0,793},{139,0,938},{7,0,464},{8,0,558},{11,0,105},{12,0, +231},{14,0,386},{15,0,102},{148,0,75},{133,10,1009},{8,0,877},{140,0,731},{139, +11,289},{10,11,249},{139,11,209},{132,11,561},{134,0,1608},{132,11,760},{134,0, +1429},{9,11,154},{140,11,485},{5,10,228},{6,10,203},{7,10,156},{8,10,347},{137, +10,265},{7,0,1010},{11,0,733},{11,0,759},{13,0,34},{14,0,427},{146,0,45},{7,10, +1131},{135,10,1468},{136,11,255},{7,0,1656},{9,0,369},{10,0,338},{10,0,490},{11, +0,154},{11,0,545},{11,0,775},{13,0,77},{141,0,274},{133,11,621},{134,0,1038},{4, +11,368},{135,11,641},{6,0,2010},{8,0,979},{8,0,985},{10,0,951},{138,0,1011},{134 +,0,1005},{5,10,291},{5,10,318},{7,10,765},{9,10,389},{12,10,548},{147,0,121},{5, +0,20},{6,0,298},{7,0,659},{137,0,219},{7,0,1440},{11,0,854},{11,0,872},{11,0,921 +},{12,0,551},{13,0,472},{142,0,367},{5,0,490},{6,0,615},{6,0,620},{135,0,683},{6 +,0,1070},{134,0,1597},{139,0,522},{132,0,439},{136,0,669},{6,0,766},{6,0,1143},{ +6,0,1245},{10,10,525},{139,10,82},{9,11,92},{147,11,91},{6,0,668},{134,0,1218},{ +6,11,525},{9,11,876},{140,11,284},{132,0,233},{136,0,547},{132,10,422},{5,10,355 +},{145,10,0},{6,11,300},{135,11,1515},{4,0,482},{137,10,905},{4,0,886},{5,11,594 +},{135,0,346},{133,10,865},{5,10,914},{134,10,1625},{135,0,334},{5,0,795},{5,10, +234},{134,0,1741},{135,10,1383},{6,11,1641},{136,11,820},{135,0,371},{7,11,1313} +,{138,11,660},{135,10,1312},{135,0,622},{7,0,625},{135,0,1750},{135,0,339},{4,0, +203},{135,0,1936},{15,0,29},{15,11,29},{16,0,38},{144,11,38},{5,0,338},{135,0, +1256},{135,10,1493},{6,10,421},{7,10,61},{7,10,1540},{10,0,130},{138,10,501},{6, +11,389},{7,11,149},{9,11,142},{138,11,94},{137,10,341},{11,0,678},{12,0,307},{ +142,10,98},{6,11,8},{7,11,1881},{136,11,91},{135,0,2044},{6,0,770},{6,0,802},{6, +0,812},{6,10,102},{7,0,311},{7,10,72},{9,0,308},{12,0,255},{15,10,142},{147,10, +67},{151,10,30},{135,10,823},{135,0,1266},{135,11,1746},{135,10,1870},{4,0,400}, +{5,0,267},{135,0,232},{7,11,24},{11,11,542},{139,11,852},{135,11,1739},{4,11,503 +},{135,11,1661},{5,11,130},{7,11,1314},{9,11,610},{10,11,718},{11,11,601},{11,11 +,819},{11,11,946},{140,11,536},{10,11,149},{11,11,280},{142,11,336},{7,0,739},{7 +,11,1946},{8,10,48},{8,10,88},{8,10,582},{8,10,681},{9,10,373},{9,10,864},{11,0, +690},{11,10,157},{11,10,843},{148,10,27},{134,0,990},{4,10,88},{5,10,137},{5,10, +174},{5,10,777},{6,10,1664},{6,10,1725},{7,10,77},{7,10,426},{7,10,1317},{7,10, +1355},{8,10,126},{8,10,563},{9,10,523},{9,10,750},{10,10,310},{10,10,836},{11,10 +,42},{11,10,318},{11,10,731},{12,10,68},{12,10,92},{12,10,507},{12,10,692},{13, +10,81},{13,10,238},{13,10,374},{14,10,436},{18,10,138},{19,10,78},{19,10,111},{ +20,10,55},{20,10,77},{148,10,92},{141,10,418},{4,10,938},{135,0,1831},{6,0,776}, +{134,0,915},{138,10,351},{5,11,348},{6,10,1668},{6,11,522},{7,10,1499},{8,10,117 +},{9,10,314},{138,10,174},{135,10,707},{132,0,613},{133,10,403},{132,11,392},{5, +11,433},{9,11,633},{139,11,629},{133,0,763},{132,0,878},{132,0,977},{132,0,100}, +{4,10,44},{5,10,311},{6,0,463},{7,10,639},{7,10,762},{7,10,1827},{9,10,8},{9,10, +462},{148,10,83},{134,11,234},{4,10,346},{7,10,115},{9,10,180},{9,10,456},{138, +10,363},{5,0,362},{5,0,443},{6,0,318},{7,0,1019},{139,0,623},{5,0,463},{7,11,140 +},{7,11,1950},{8,0,296},{8,11,680},{11,11,817},{147,11,88},{7,11,1222},{138,11, +386},{142,0,137},{132,0,454},{6,11,5},{7,0,1914},{7,10,1051},{9,10,545},{11,11, +249},{12,11,313},{16,11,66},{145,11,26},{135,0,1527},{145,0,58},{148,11,59},{5,0 +,48},{5,0,404},{6,0,557},{7,0,458},{8,0,597},{10,0,455},{10,0,606},{11,0,49},{11 +,0,548},{12,0,476},{13,0,18},{141,0,450},{5,11,963},{134,11,1773},{133,0,729},{ +138,11,586},{5,0,442},{135,0,1984},{134,0,449},{144,0,40},{4,0,853},{7,11,180},{ +8,11,509},{136,11,792},{6,10,185},{7,10,1899},{9,10,875},{139,10,673},{134,11, +524},{4,10,327},{5,10,478},{7,10,1332},{8,10,753},{140,0,227},{5,10,1020},{5,10, +1022},{134,0,1491},{4,10,103},{133,10,401},{132,11,931},{4,10,499},{135,10,1421} +,{5,0,55},{7,0,376},{140,0,161},{133,0,450},{6,0,1174},{134,0,1562},{7,11,1837}, +{10,0,62},{141,0,400},{140,0,207},{135,0,869},{4,11,773},{5,11,618},{137,11,756} +,{132,10,96},{4,0,213},{7,0,223},{7,10,968},{136,0,80},{4,11,90},{5,11,337},{5, +11,545},{7,11,754},{9,11,186},{10,11,72},{10,11,782},{11,11,513},{11,11,577},{11 +,11,610},{11,11,889},{11,11,961},{12,11,354},{12,11,362},{12,11,461},{12,11,595} +,{13,11,79},{143,11,121},{7,0,381},{7,0,806},{7,0,820},{8,0,354},{8,0,437},{8,0, +787},{9,0,657},{10,0,58},{10,0,339},{10,0,749},{11,0,914},{12,0,162},{13,0,75},{ +14,0,106},{14,0,198},{14,0,320},{14,0,413},{146,0,43},{136,0,747},{136,0,954},{ +134,0,1073},{135,0,556},{7,11,151},{9,11,329},{139,11,254},{5,0,692},{134,0,1395 +},{6,10,563},{137,10,224},{134,0,191},{132,0,804},{9,11,187},{10,11,36},{17,11, +44},{146,11,64},{7,11,165},{7,11,919},{136,11,517},{4,11,506},{5,11,295},{7,11, +1680},{15,11,14},{144,11,5},{4,0,706},{6,0,162},{7,0,1960},{136,0,831},{135,11, +1376},{7,11,987},{9,11,688},{10,11,522},{11,11,788},{140,11,566},{150,0,35},{138 +,0,426},{135,0,1235},{135,11,1741},{7,11,389},{7,11,700},{7,11,940},{8,11,514},{ +9,11,116},{9,11,535},{10,11,118},{11,11,107},{11,11,148},{11,11,922},{12,11,254} +,{12,11,421},{142,11,238},{134,0,1234},{132,11,743},{4,10,910},{5,10,832},{135, +11,1335},{141,0,96},{135,11,185},{146,0,149},{4,0,204},{137,0,902},{4,11,784},{ +133,11,745},{136,0,833},{136,0,949},{5,11,81},{7,0,366},{7,11,146},{7,11,1342},{ +7,11,1446},{8,11,53},{8,11,561},{8,11,694},{8,11,754},{9,0,287},{9,11,97},{9,11, +115},{9,11,894},{10,11,462},{10,11,813},{11,11,230},{11,11,657},{11,11,699},{11, +11,748},{12,0,199},{12,0,556},{12,0,577},{12,11,119},{12,11,200},{12,11,283},{14 +,11,273},{145,11,15},{5,11,408},{137,11,747},{9,11,498},{140,11,181},{6,0,2020}, +{136,0,992},{5,0,356},{135,0,224},{134,0,784},{7,0,630},{8,10,528},{9,0,567},{9, +10,348},{11,0,150},{11,0,444},{141,0,119},{134,0,539},{4,10,20},{133,10,616},{ +142,0,27},{7,11,30},{8,11,86},{8,11,315},{8,11,700},{9,11,576},{9,11,858},{11,11 +,310},{11,11,888},{11,11,904},{12,11,361},{141,11,248},{138,11,839},{134,0,755}, +{134,0,1063},{7,10,1091},{135,10,1765},{134,11,428},{7,11,524},{8,11,169},{8,11, +234},{9,11,480},{138,11,646},{139,0,814},{7,11,1462},{139,11,659},{4,10,26},{5, +10,429},{6,10,245},{7,10,704},{7,10,1379},{135,10,1474},{7,11,1205},{138,11,637} +,{139,11,803},{132,10,621},{136,0,987},{4,11,266},{8,11,4},{9,11,39},{10,11,166} +,{11,11,918},{12,11,635},{20,11,10},{22,11,27},{150,11,43},{4,0,235},{135,0,255} +,{4,0,194},{5,0,584},{6,0,384},{7,0,583},{10,0,761},{11,0,760},{139,0,851},{133, +10,542},{134,0,1086},{133,10,868},{8,0,1016},{136,0,1018},{7,0,1396},{7,11,1396} +,{136,10,433},{135,10,1495},{138,10,215},{141,10,124},{7,11,157},{8,11,279},{9, +11,759},{16,11,31},{16,11,39},{16,11,75},{18,11,24},{20,11,42},{152,11,1},{5,0, +562},{134,11,604},{134,0,913},{5,0,191},{137,0,271},{4,0,470},{6,0,153},{7,0, +1503},{7,0,1923},{10,0,701},{11,0,132},{11,0,227},{11,0,320},{11,0,436},{11,0, +525},{11,0,855},{11,0,873},{12,0,41},{12,0,286},{13,0,103},{13,0,284},{14,0,255} +,{14,0,262},{15,0,117},{143,0,127},{7,0,475},{12,0,45},{147,10,112},{132,11,567} +,{137,11,859},{6,0,713},{6,0,969},{6,0,1290},{134,0,1551},{133,0,327},{6,0,552}, +{6,0,1292},{7,0,1754},{137,0,604},{4,0,223},{5,11,762},{6,0,359},{7,11,1880},{9, +11,680},{11,0,3},{11,11,798},{13,0,108},{14,0,89},{144,0,22},{5,0,80},{6,0,405}, +{7,0,403},{7,0,1502},{8,0,456},{9,0,487},{9,0,853},{9,0,889},{10,0,309},{11,0, +721},{11,0,994},{12,0,430},{141,0,165},{133,11,298},{132,10,647},{134,0,2016},{ +18,10,10},{146,11,10},{4,0,453},{5,0,887},{6,0,535},{8,0,6},{8,0,543},{136,0,826 +},{136,0,975},{10,0,961},{138,0,962},{138,10,220},{6,0,1891},{6,0,1893},{9,0,916 +},{9,0,965},{9,0,972},{12,0,801},{12,0,859},{12,0,883},{15,0,226},{149,0,51},{ +132,10,109},{135,11,267},{7,11,92},{7,11,182},{8,11,453},{9,11,204},{11,11,950}, +{12,11,94},{12,11,644},{16,11,20},{16,11,70},{16,11,90},{147,11,55},{134,10,1746 +},{6,11,71},{7,11,845},{7,11,1308},{8,11,160},{137,11,318},{5,0,101},{6,0,88},{7 +,0,263},{7,0,628},{7,0,1677},{7,11,237},{8,0,349},{8,11,664},{9,0,100},{9,11,42} +,{9,11,266},{9,11,380},{9,11,645},{10,0,677},{10,11,177},{10,11,276},{14,0,169}, +{14,0,302},{14,0,313},{15,0,48},{143,0,84},{138,11,69},{4,0,310},{7,0,708},{7,0, +996},{9,0,795},{10,0,390},{10,0,733},{11,0,451},{12,0,249},{14,0,115},{14,0,286} +,{143,0,100},{4,10,40},{5,0,587},{10,10,67},{11,10,117},{11,10,768},{139,10,935} +,{6,0,1942},{7,0,512},{136,0,983},{7,10,992},{8,10,301},{9,10,722},{12,10,63},{ +13,10,29},{14,10,161},{143,10,18},{136,11,76},{139,10,923},{134,0,645},{134,0, +851},{4,0,498},{132,11,293},{7,0,217},{8,0,140},{10,0,610},{14,11,352},{17,11,53 +},{18,11,146},{18,11,152},{19,11,11},{150,11,54},{134,0,1448},{138,11,841},{133, +0,905},{4,11,605},{7,11,518},{7,11,1282},{7,11,1918},{10,11,180},{139,11,218},{ +139,11,917},{135,10,825},{140,10,328},{4,0,456},{7,0,105},{7,0,358},{7,0,1637},{ +8,0,643},{139,0,483},{134,0,792},{6,11,96},{135,11,1426},{137,11,691},{4,11,651} +,{133,11,289},{7,11,688},{8,11,35},{9,11,511},{10,11,767},{147,11,118},{150,0,56 +},{5,0,243},{5,0,535},{6,10,204},{10,10,320},{10,10,583},{13,10,502},{14,10,72}, +{14,10,274},{14,10,312},{14,10,344},{15,10,159},{16,10,62},{16,10,69},{17,10,30} +,{18,10,42},{18,10,53},{18,10,84},{18,10,140},{19,10,68},{19,10,85},{20,10,5},{ +20,10,45},{20,10,101},{22,10,7},{150,10,20},{4,10,558},{6,10,390},{7,10,162},{7, +10,689},{9,10,360},{138,10,653},{146,11,23},{135,0,1748},{5,10,856},{6,10,1672}, +{6,10,1757},{134,10,1781},{4,11,704},{5,0,539},{5,0,754},{134,0,876},{135,11, +1078},{5,10,92},{10,10,736},{140,10,102},{5,10,590},{9,10,213},{145,0,91},{134,0 +,1565},{6,0,91},{135,0,435},{4,0,939},{140,0,792},{134,0,1399},{4,0,16},{4,11, +720},{5,0,316},{5,0,842},{5,11,306},{6,0,370},{6,0,1778},{8,0,166},{11,0,812},{ +12,0,206},{12,0,351},{14,0,418},{16,0,15},{16,0,34},{18,0,3},{19,0,3},{19,0,7},{ +20,0,4},{149,0,21},{144,0,95},{133,11,431},{132,11,234},{135,0,551},{4,0,999},{6 +,0,1966},{134,0,2042},{7,0,619},{10,0,547},{11,0,122},{12,0,601},{15,0,7},{148,0 +,20},{5,11,464},{6,11,236},{7,11,276},{7,11,696},{7,11,914},{7,11,1108},{7,11, +1448},{9,11,15},{9,11,564},{10,11,14},{12,11,565},{13,11,449},{14,11,53},{15,11, +13},{16,11,64},{145,11,41},{6,0,884},{6,0,1019},{134,0,1150},{6,11,1767},{12,11, +194},{145,11,107},{136,10,503},{133,11,840},{6,10,466},{135,0,671},{132,0,888},{ +4,0,149},{138,0,368},{4,0,154},{7,0,1134},{136,0,105},{135,0,983},{9,11,642},{11 +,11,236},{142,11,193},{4,0,31},{6,0,429},{7,0,962},{9,0,458},{139,0,691},{6,0, +643},{134,0,1102},{132,0,312},{4,11,68},{5,11,634},{6,11,386},{7,11,794},{8,11, +273},{9,11,563},{10,11,105},{10,11,171},{11,11,94},{139,11,354},{133,0,740},{135 +,0,1642},{4,11,95},{7,11,416},{8,11,211},{139,11,830},{132,0,236},{138,10,241},{ +7,11,731},{13,11,20},{143,11,11},{5,0,836},{5,0,857},{6,0,1680},{135,0,59},{10,0 +,68},{11,0,494},{152,11,6},{4,0,81},{139,0,867},{135,0,795},{133,11,689},{4,0, +1001},{5,0,282},{6,0,1932},{6,0,1977},{6,0,1987},{6,0,1992},{8,0,650},{8,0,919}, +{8,0,920},{8,0,923},{8,0,926},{8,0,927},{8,0,931},{8,0,939},{8,0,947},{8,0,956}, +{8,0,997},{9,0,907},{10,0,950},{10,0,953},{10,0,954},{10,0,956},{10,0,958},{10,0 +,959},{10,0,964},{10,0,970},{10,0,972},{10,0,973},{10,0,975},{10,0,976},{10,0, +980},{10,0,981},{10,0,984},{10,0,988},{10,0,990},{10,0,995},{10,0,999},{10,0, +1002},{10,0,1003},{10,0,1005},{10,0,1006},{10,0,1008},{10,0,1009},{10,0,1012},{ +10,0,1014},{10,0,1015},{10,0,1019},{10,0,1020},{10,0,1022},{12,0,959},{12,0,961} +,{12,0,962},{12,0,963},{12,0,964},{12,0,965},{12,0,967},{12,0,968},{12,0,969},{ +12,0,970},{12,0,971},{12,0,972},{12,0,973},{12,0,974},{12,0,975},{12,0,976},{12, +0,977},{12,0,979},{12,0,981},{12,0,982},{12,0,983},{12,0,984},{12,0,985},{12,0, +986},{12,0,987},{12,0,989},{12,0,990},{12,0,992},{12,0,993},{12,0,995},{12,0,998 +},{12,0,999},{12,0,1000},{12,0,1001},{12,0,1002},{12,0,1004},{12,0,1005},{12,0, +1006},{12,0,1007},{12,0,1008},{12,0,1009},{12,0,1010},{12,0,1011},{12,0,1012},{ +12,0,1014},{12,0,1015},{12,0,1016},{12,0,1017},{12,0,1018},{12,0,1019},{12,0, +1022},{12,0,1023},{14,0,475},{14,0,477},{14,0,478},{14,0,479},{14,0,480},{14,0, +482},{14,0,483},{14,0,484},{14,0,485},{14,0,486},{14,0,487},{14,0,488},{14,0,489 +},{14,0,490},{14,0,491},{14,0,492},{14,0,493},{14,0,494},{14,0,495},{14,0,496},{ +14,0,497},{14,0,498},{14,0,499},{14,0,500},{14,0,501},{14,0,502},{14,0,503},{14, +0,504},{14,0,506},{14,0,507},{14,0,508},{14,0,509},{14,0,510},{14,0,511},{16,0, +113},{16,0,114},{16,0,115},{16,0,117},{16,0,118},{16,0,119},{16,0,121},{16,0,122 +},{16,0,123},{16,0,124},{16,0,125},{16,0,126},{16,0,127},{18,0,242},{18,0,243},{ +18,0,244},{18,0,245},{18,0,248},{18,0,249},{18,0,250},{18,0,251},{18,0,252},{18, +0,253},{18,0,254},{18,0,255},{20,0,125},{20,0,126},{148,0,127},{7,11,1717},{7,11 +,1769},{138,11,546},{7,11,1127},{7,11,1572},{10,11,297},{10,11,422},{11,11,764}, +{11,11,810},{12,11,264},{13,11,102},{13,11,300},{13,11,484},{14,11,147},{14,11, +229},{17,11,71},{18,11,118},{147,11,120},{6,0,1148},{134,0,1586},{132,0,775},{ +135,10,954},{133,11,864},{133,11,928},{138,11,189},{135,10,1958},{6,10,549},{8, +10,34},{8,10,283},{9,10,165},{138,10,475},{5,10,652},{5,10,701},{135,10,449},{ +135,11,695},{4,10,655},{7,10,850},{17,10,75},{146,10,137},{140,11,682},{133,11, +523},{8,0,970},{136,10,670},{136,11,555},{7,11,76},{8,11,44},{9,11,884},{10,11, +580},{11,11,399},{11,11,894},{15,11,122},{18,11,144},{147,11,61},{6,10,159},{6, +10,364},{7,10,516},{7,10,1439},{137,10,518},{4,0,71},{5,0,376},{7,0,119},{138,0, +665},{141,10,151},{11,0,827},{14,0,34},{143,0,148},{133,11,518},{4,0,479},{135, +11,1787},{135,11,1852},{135,10,993},{7,0,607},{136,0,99},{134,0,1960},{132,0,793 +},{4,0,41},{5,0,74},{7,0,1627},{11,0,871},{140,0,619},{7,0,94},{11,0,329},{11,0, +965},{12,0,241},{14,0,354},{15,0,22},{148,0,63},{7,10,501},{9,10,111},{10,10,141 +},{11,10,332},{13,10,43},{13,10,429},{14,10,130},{14,10,415},{145,10,102},{9,0, +209},{137,0,300},{134,0,1497},{138,11,255},{4,11,934},{5,11,138},{136,11,610},{ +133,0,98},{6,0,1316},{10,11,804},{138,11,832},{8,11,96},{9,11,36},{10,11,607},{ +11,11,423},{11,11,442},{12,11,309},{14,11,199},{15,11,90},{145,11,110},{132,0, +463},{5,10,149},{136,10,233},{133,10,935},{4,11,652},{8,11,320},{9,11,13},{9,11, +398},{9,11,727},{10,11,75},{10,11,184},{10,11,230},{10,11,564},{10,11,569},{11, +11,973},{12,11,70},{12,11,189},{13,11,57},{13,11,257},{22,11,6},{150,11,16},{142 +,0,291},{12,10,582},{146,10,131},{136,10,801},{133,0,984},{145,11,116},{4,11,692 +},{133,11,321},{4,0,182},{6,0,205},{135,0,220},{4,0,42},{9,0,205},{9,0,786},{138 +,0,659},{6,0,801},{11,11,130},{140,11,609},{132,0,635},{5,11,345},{135,11,1016}, +{139,0,533},{132,0,371},{4,0,272},{135,0,836},{6,0,1282},{135,11,1100},{5,0,825} +,{134,0,1640},{135,11,1325},{133,11,673},{4,11,287},{133,11,1018},{135,0,357},{6 +,0,467},{137,0,879},{7,0,317},{135,0,569},{6,0,924},{134,0,1588},{5,10,406},{5, +11,34},{10,11,724},{12,11,444},{13,11,354},{18,11,32},{23,11,24},{23,11,31},{152 +,11,5},{6,0,1795},{6,0,1835},{6,0,1836},{6,0,1856},{8,0,844},{8,0,849},{8,0,854} +,{8,0,870},{8,0,887},{10,0,852},{138,0,942},{6,10,69},{135,10,117},{137,0,307},{ +4,0,944},{6,0,1799},{6,0,1825},{10,0,848},{10,0,875},{10,0,895},{10,0,899},{10,0 +,902},{140,0,773},{11,0,43},{13,0,72},{141,0,142},{135,10,1830},{134,11,382},{4, +10,432},{135,10,824},{132,11,329},{7,0,1820},{139,11,124},{133,10,826},{133,0, +525},{132,11,906},{7,11,1940},{136,11,366},{138,11,10},{4,11,123},{4,11,649},{5, +11,605},{7,11,1509},{136,11,36},{6,0,110},{135,0,1681},{133,0,493},{133,11,767}, +{4,0,174},{135,0,911},{138,11,786},{8,0,417},{137,0,782},{133,10,1000},{7,0,733} +,{137,0,583},{4,10,297},{6,10,529},{7,10,152},{7,10,713},{7,10,1845},{8,10,710}, +{8,10,717},{12,10,639},{140,10,685},{4,0,32},{5,0,215},{6,0,269},{7,0,1782},{7,0 +,1892},{10,0,16},{11,0,822},{11,0,954},{141,0,481},{4,11,273},{5,11,658},{133,11 +,995},{136,0,477},{134,11,72},{135,11,1345},{4,10,520},{5,0,308},{7,0,1088},{135 +,10,575},{133,11,589},{5,0,126},{8,0,297},{9,0,366},{140,0,374},{7,0,1551},{139, +0,361},{5,11,117},{6,11,514},{6,11,541},{7,11,1164},{7,11,1436},{8,11,220},{8,11 +,648},{10,11,688},{139,11,560},{133,11,686},{4,0,946},{6,0,1807},{8,0,871},{10,0 +,854},{10,0,870},{10,0,888},{10,0,897},{10,0,920},{12,0,722},{12,0,761},{12,0, +763},{12,0,764},{14,0,454},{14,0,465},{16,0,107},{18,0,167},{18,0,168},{146,0, +172},{132,0,175},{135,0,1307},{132,0,685},{135,11,1834},{133,0,797},{6,0,745},{6 +,0,858},{134,0,963},{133,0,565},{5,10,397},{6,10,154},{7,10,676},{7,11,196},{8, +10,443},{8,10,609},{9,10,24},{9,10,325},{10,10,35},{10,11,765},{11,10,535},{11, +10,672},{11,10,1018},{11,11,347},{11,11,552},{11,11,576},{11,11,790},{12,10,637} +,{12,11,263},{13,11,246},{13,11,270},{13,11,395},{14,11,74},{14,11,176},{14,11, +190},{14,11,398},{14,11,412},{15,11,32},{15,11,63},{16,10,30},{16,11,88},{147,11 +,105},{13,11,84},{141,11,122},{4,0,252},{7,0,1068},{10,0,434},{11,0,228},{11,0, +426},{13,0,231},{18,0,106},{148,0,87},{137,0,826},{4,11,589},{139,11,282},{5,11, +381},{135,11,1792},{132,0,791},{5,0,231},{5,10,981},{138,0,509},{7,0,601},{9,0, +277},{9,0,674},{10,0,178},{10,0,418},{10,0,571},{11,0,531},{12,0,113},{12,0,475} +,{13,0,99},{142,0,428},{4,10,56},{7,10,1791},{7,11,616},{8,10,607},{8,10,651},{ +10,11,413},{11,10,465},{11,10,835},{12,10,337},{141,10,480},{7,0,1591},{144,0,43 +},{9,10,158},{138,10,411},{135,0,1683},{8,0,289},{11,0,45},{12,0,278},{140,0,537 +},{6,11,120},{7,11,1188},{7,11,1710},{8,11,286},{9,11,667},{11,11,592},{139,11, +730},{136,10,617},{135,0,1120},{135,11,1146},{139,10,563},{4,10,369},{4,11,352}, +{135,11,687},{143,11,38},{4,0,399},{5,0,119},{5,0,494},{7,0,751},{9,0,556},{14, +11,179},{15,11,151},{150,11,11},{4,11,192},{5,11,49},{6,11,200},{6,11,293},{6,11 +,1696},{135,11,488},{4,0,398},{133,0,660},{6,10,622},{135,0,1030},{135,11,595},{ +141,0,168},{132,11,147},{7,0,973},{10,10,624},{142,10,279},{132,10,363},{132,0, +642},{133,11,934},{134,0,1615},{7,11,505},{135,11,523},{7,0,594},{7,0,851},{7,0, +1858},{9,0,411},{9,0,574},{9,0,666},{9,0,737},{10,0,346},{10,0,712},{11,0,246},{ +11,0,432},{11,0,517},{11,0,647},{11,0,679},{11,0,727},{12,0,304},{12,0,305},{12, +0,323},{12,0,483},{12,0,572},{12,0,593},{12,0,602},{13,0,95},{13,0,101},{13,0, +171},{13,0,315},{13,0,378},{13,0,425},{13,0,475},{14,0,63},{14,0,380},{14,0,384} +,{15,0,133},{18,0,112},{148,0,72},{135,0,1093},{132,0,679},{8,0,913},{10,0,903}, +{10,0,915},{10,11,438},{12,0,648},{12,0,649},{14,0,455},{144,0,112},{137,0,203}, +{134,10,292},{134,0,1492},{5,10,177},{6,10,616},{7,0,1374},{7,10,827},{8,0,540}, +{9,10,525},{138,10,656},{135,0,1486},{9,0,714},{138,10,31},{136,0,825},{134,0, +1511},{132,11,637},{134,0,952},{4,10,161},{133,10,631},{5,0,143},{5,0,769},{6,0, +1760},{7,0,682},{7,0,1992},{136,0,736},{132,0,700},{134,0,1540},{132,11,777},{9, +11,867},{138,11,837},{7,0,1557},{135,10,1684},{133,0,860},{6,0,422},{7,0,0},{7,0 +,1544},{9,0,605},{9,10,469},{9,10,709},{11,0,990},{12,0,235},{12,0,453},{12,10, +512},{13,0,47},{13,0,266},{14,10,65},{145,10,12},{10,10,229},{11,0,807},{11,10, +73},{139,10,376},{6,11,170},{7,11,1080},{8,11,395},{8,11,487},{11,11,125},{141, +11,147},{5,0,515},{137,0,131},{7,0,1605},{11,0,962},{146,0,139},{132,0,646},{4,0 +,396},{7,0,728},{9,0,117},{13,0,202},{148,0,51},{4,11,535},{6,0,121},{6,0,124},{ +6,0,357},{6,10,558},{7,0,1138},{7,0,1295},{7,10,651},{8,0,162},{8,0,508},{8,11, +618},{9,10,0},{10,10,34},{11,0,655},{139,10,1008},{135,11,1245},{138,0,357},{150 +,11,23},{133,0,237},{135,0,1784},{7,10,1832},{138,10,374},{132,0,713},{132,11,46 +},{5,11,811},{6,0,1536},{6,11,1679},{6,11,1714},{7,11,2032},{138,0,348},{11,11, +182},{142,11,195},{6,0,523},{7,0,738},{7,10,771},{7,10,1731},{9,10,405},{138,10, +421},{7,11,1458},{9,11,407},{139,11,15},{6,11,34},{7,11,69},{7,11,640},{7,11, +1089},{8,11,708},{8,11,721},{9,11,363},{9,11,643},{10,11,628},{148,11,98},{133,0 +,434},{135,0,1877},{7,0,571},{138,0,366},{5,10,881},{133,10,885},{9,0,513},{10,0 +,25},{10,0,39},{12,0,122},{140,0,187},{132,0,580},{5,10,142},{134,10,546},{132, +11,462},{137,0,873},{5,10,466},{11,10,571},{12,10,198},{13,10,283},{14,10,186},{ +15,10,21},{143,10,103},{4,10,185},{5,10,257},{5,10,839},{5,10,936},{7,0,171},{9, +10,399},{10,10,258},{10,10,395},{10,10,734},{11,10,1014},{12,10,23},{13,10,350}, +{14,10,150},{147,10,6},{134,0,625},{7,0,107},{7,0,838},{8,0,550},{138,0,401},{5, +11,73},{6,11,23},{134,11,338},{4,0,943},{6,0,1850},{12,0,713},{142,0,434},{7,10, +404},{7,10,1377},{7,10,1430},{7,10,2017},{8,10,149},{8,10,239},{8,10,512},{8,10, +793},{8,10,818},{9,10,474},{9,10,595},{10,10,122},{10,10,565},{10,10,649},{10,10 +,783},{11,0,588},{11,0,864},{11,0,936},{11,0,968},{11,10,239},{11,10,295},{11,10 +,447},{11,10,528},{11,10,639},{11,10,800},{12,0,73},{12,0,343},{12,0,394},{12,10 +,25},{12,10,157},{12,10,316},{12,10,390},{12,10,391},{12,10,395},{12,10,478},{12 +,10,503},{12,10,592},{12,10,680},{13,0,275},{13,10,50},{13,10,53},{13,10,132},{ +13,10,198},{13,10,322},{13,10,415},{13,10,511},{14,0,257},{14,10,71},{14,10,395} +,{15,0,160},{15,10,71},{15,10,136},{17,10,123},{18,10,93},{147,10,58},{133,0,768 +},{11,0,103},{142,0,0},{136,10,712},{132,0,799},{132,0,894},{7,11,725},{8,11,498 +},{139,11,268},{135,11,1798},{135,11,773},{141,11,360},{4,10,377},{152,10,13},{ +135,0,1673},{132,11,583},{134,0,1052},{133,11,220},{140,11,69},{132,11,544},{4, +10,180},{135,10,1906},{134,0,272},{4,0,441},{134,0,1421},{4,0,9},{5,0,128},{7,0, +368},{11,0,480},{148,0,3},{5,11,176},{6,11,437},{6,11,564},{11,11,181},{141,11, +183},{132,10,491},{7,0,1182},{141,11,67},{4,10,171},{6,0,1346},{138,10,234},{4, +10,586},{7,10,1186},{138,10,631},{136,0,682},{134,0,1004},{15,0,24},{143,11,24}, +{134,0,968},{4,0,2},{6,0,742},{6,0,793},{7,0,545},{7,0,894},{9,10,931},{10,10, +334},{148,10,71},{136,11,600},{133,10,765},{9,0,769},{140,0,185},{4,11,790},{5, +11,273},{134,11,394},{7,0,474},{137,0,578},{4,11,135},{6,11,127},{7,11,1185},{7, +11,1511},{8,11,613},{11,11,5},{12,11,133},{12,11,495},{12,11,586},{14,11,385},{ +15,11,118},{17,11,20},{146,11,98},{133,10,424},{5,0,530},{142,0,113},{6,11,230}, +{7,11,961},{7,11,1085},{136,11,462},{7,11,1954},{137,11,636},{136,10,714},{149, +11,6},{135,10,685},{9,10,420},{10,10,269},{10,10,285},{10,10,576},{11,10,397},{ +13,10,175},{145,10,90},{132,10,429},{5,0,556},{5,11,162},{136,11,68},{132,11,654 +},{4,11,156},{7,11,998},{7,11,1045},{7,11,1860},{9,11,48},{9,11,692},{11,11,419} +,{139,11,602},{6,0,1317},{7,11,1276},{8,0,16},{8,11,474},{9,0,825},{9,11,652},{ +140,0,568},{7,10,18},{7,10,699},{7,10,1966},{8,10,752},{9,10,273},{9,10,412},{9, +10,703},{10,10,71},{10,10,427},{10,10,508},{146,0,97},{7,11,1454},{10,0,703},{ +138,11,703},{4,10,53},{5,10,186},{135,10,752},{134,0,892},{134,0,1571},{8,10,575 +},{10,10,289},{139,10,319},{6,0,186},{137,0,426},{134,0,1101},{132,10,675},{132, +0,585},{6,0,1870},{137,0,937},{152,11,10},{9,11,197},{10,11,300},{12,11,473},{13 +,11,90},{141,11,405},{4,0,93},{5,0,252},{6,0,229},{7,0,291},{9,0,550},{139,0,644 +},{137,0,749},{6,10,209},{8,10,468},{9,0,162},{9,10,210},{11,10,36},{12,10,28},{ +12,10,630},{13,10,21},{13,10,349},{14,10,7},{145,10,13},{132,0,381},{132,11,606} +,{4,10,342},{135,10,1179},{7,11,1587},{7,11,1707},{10,11,528},{139,11,504},{12, +11,39},{13,11,265},{141,11,439},{4,10,928},{133,10,910},{7,10,1838},{7,11,1978}, +{136,11,676},{6,0,762},{6,0,796},{134,0,956},{4,10,318},{4,10,496},{7,10,856},{ +139,10,654},{137,11,242},{4,11,361},{133,11,315},{132,11,461},{132,11,472},{132, +0,857},{5,0,21},{6,0,77},{6,0,157},{7,0,974},{7,0,1301},{7,0,1339},{7,0,1490},{7 +,0,1873},{7,10,915},{8,10,247},{9,0,628},{147,10,0},{4,10,202},{5,10,382},{6,10, +454},{7,10,936},{7,10,1803},{8,10,758},{9,10,375},{9,10,895},{10,10,743},{10,10, +792},{11,10,978},{11,10,1012},{142,10,109},{7,11,617},{10,11,498},{11,11,501},{ +12,11,16},{140,11,150},{7,10,1150},{7,10,1425},{7,10,1453},{10,11,747},{140,10, +513},{133,11,155},{11,0,919},{141,0,409},{138,10,791},{10,0,633},{139,11,729},{7 +,11,163},{8,11,319},{9,11,402},{10,11,24},{10,11,681},{11,11,200},{11,11,567},{ +12,11,253},{12,11,410},{142,11,219},{5,11,475},{7,11,1780},{9,11,230},{11,11,297 +},{11,11,558},{14,11,322},{147,11,76},{6,10,445},{7,0,332},{137,10,909},{135,11, +1956},{136,11,274},{134,10,578},{135,0,1489},{135,11,1848},{5,11,944},{134,11, +1769},{132,11,144},{136,10,766},{4,0,832},{135,10,541},{8,0,398},{9,0,681},{139, +0,632},{136,0,645},{9,0,791},{10,0,93},{16,0,13},{17,0,23},{18,0,135},{19,0,12}, +{20,0,1},{20,0,12},{148,0,14},{6,11,247},{137,11,555},{134,0,20},{132,0,800},{ +135,0,1841},{139,10,983},{137,10,768},{132,10,584},{141,11,51},{4,11,620},{6,0, +1993},{138,11,280},{136,0,769},{7,11,1810},{11,0,290},{11,0,665},{11,11,866},{12 +,11,103},{13,11,495},{17,11,67},{147,11,74},{134,0,1426},{139,0,60},{4,10,326},{ +135,10,1770},{4,10,226},{7,0,1874},{137,0,641},{5,10,426},{6,0,644},{8,10,30},{9 +,10,2},{11,10,549},{147,10,122},{5,11,428},{138,11,442},{135,11,1871},{135,0, +1757},{147,10,117},{135,0,937},{135,0,1652},{6,0,654},{134,0,1476},{133,11,99},{ +135,0,527},{132,10,345},{4,10,385},{4,11,397},{7,10,265},{135,10,587},{4,0,579}, +{5,0,226},{5,0,323},{135,0,960},{134,0,1486},{8,11,502},{144,11,9},{4,10,347},{5 +,10,423},{5,10,996},{135,10,1329},{7,11,727},{146,11,73},{4,11,485},{7,10,1259}, +{7,11,353},{7,11,1523},{9,10,125},{139,10,65},{5,10,136},{6,0,325},{6,11,366},{7 +,11,1384},{7,11,1601},{136,10,644},{138,11,160},{6,0,1345},{137,11,282},{18,0,91 +},{147,0,70},{136,0,404},{4,11,157},{133,11,471},{133,0,973},{6,0,135},{135,0, +1176},{8,11,116},{11,11,551},{142,11,159},{4,0,549},{4,10,433},{133,10,719},{136 +,0,976},{5,11,160},{7,11,363},{7,11,589},{10,11,170},{141,11,55},{144,0,21},{144 +,0,51},{135,0,314},{135,10,1363},{4,11,108},{7,11,405},{10,11,491},{139,11,498}, +{146,0,4},{4,10,555},{8,10,536},{10,10,288},{139,10,1005},{135,11,1005},{6,0,281 +},{7,0,6},{8,0,282},{8,0,480},{8,0,499},{9,0,198},{10,0,143},{10,0,169},{10,0, +211},{10,0,417},{10,0,574},{11,0,147},{11,0,395},{12,0,75},{12,0,407},{12,0,608} +,{13,0,500},{142,0,251},{6,0,1093},{6,0,1405},{9,10,370},{138,10,90},{4,11,926}, +{133,11,983},{135,0,1776},{134,0,1528},{132,0,419},{132,11,538},{6,11,294},{7,11 +,1267},{136,11,624},{135,11,1772},{138,11,301},{4,10,257},{135,10,2031},{4,0,138 +},{7,0,1012},{7,0,1280},{7,10,1768},{137,0,76},{132,11,757},{5,0,29},{140,0,638} +,{7,11,655},{135,11,1844},{6,11,257},{7,0,1418},{135,11,1522},{8,11,469},{138,11 +,47},{142,11,278},{6,10,83},{6,10,1733},{135,10,1389},{11,11,204},{11,11,243},{ +140,11,293},{135,11,1875},{6,0,1710},{135,0,2038},{137,11,299},{4,0,17},{5,0,23} +,{7,0,995},{11,0,383},{11,0,437},{12,0,460},{140,0,532},{133,0,862},{137,10,696} +,{6,0,592},{138,0,946},{138,11,599},{7,10,1718},{9,10,95},{9,10,274},{10,10,279} +,{10,10,317},{10,10,420},{11,10,303},{11,10,808},{12,10,134},{12,10,367},{13,10, +149},{13,10,347},{14,10,349},{14,10,406},{18,10,22},{18,10,89},{18,10,122},{147, +10,47},{8,0,70},{12,0,171},{141,0,272},{133,10,26},{132,10,550},{137,0,812},{10, +0,233},{139,0,76},{134,0,988},{134,0,442},{136,10,822},{4,10,902},{5,10,809},{6, +10,122},{135,0,896},{5,11,150},{7,11,106},{8,11,603},{9,11,593},{9,11,634},{10, +11,44},{10,11,173},{11,11,462},{11,11,515},{13,11,216},{13,11,288},{142,11,400}, +{136,0,483},{135,10,262},{5,10,620},{134,0,1709},{4,10,34},{5,10,574},{7,10,279} +,{7,10,1624},{136,10,601},{137,10,170},{147,0,119},{12,11,108},{141,11,291},{11, +0,69},{12,0,105},{12,0,117},{13,0,213},{14,0,13},{14,0,62},{14,0,177},{14,0,421} +,{15,0,19},{146,0,141},{137,0,309},{11,11,278},{142,11,73},{7,0,608},{7,0,976},{ +9,0,146},{10,0,206},{10,0,596},{13,0,218},{142,0,153},{133,10,332},{6,10,261},{8 +,10,182},{139,10,943},{4,11,493},{144,11,55},{134,10,1721},{132,0,768},{4,10,933 +},{133,10,880},{7,11,555},{7,11,1316},{7,11,1412},{7,11,1839},{9,11,192},{9,11, +589},{11,11,241},{11,11,676},{11,11,811},{11,11,891},{12,11,140},{12,11,346},{12 +,11,479},{13,11,30},{13,11,49},{13,11,381},{14,11,188},{15,11,150},{16,11,76},{ +18,11,30},{148,11,52},{4,0,518},{135,0,1136},{6,11,568},{7,11,112},{7,11,1804},{ +8,11,362},{8,11,410},{8,11,830},{9,11,514},{11,11,649},{142,11,157},{135,11,673} +,{8,0,689},{137,0,863},{4,0,18},{4,11,625},{7,0,145},{7,0,444},{7,0,1278},{8,0, +49},{8,0,400},{9,0,71},{9,0,250},{10,0,459},{12,0,160},{144,0,24},{140,0,1020},{ +4,0,997},{6,0,1946},{6,0,1984},{134,0,1998},{6,11,16},{6,11,158},{7,11,43},{7,11 +,129},{7,11,181},{8,11,276},{8,11,377},{10,11,523},{11,11,816},{12,11,455},{13, +11,303},{142,11,135},{133,10,812},{134,0,658},{4,11,1},{7,11,1143},{7,11,1463},{ +8,11,61},{9,11,207},{9,11,390},{9,11,467},{139,11,836},{150,11,26},{140,0,106},{ +4,10,137},{6,0,1827},{7,10,1178},{7,10,1520},{7,11,1319},{10,0,931},{18,0,166},{ +148,0,114},{133,0,1010},{4,11,723},{5,11,895},{7,11,1031},{8,11,199},{8,11,340}, +{9,11,153},{9,11,215},{10,11,21},{10,11,59},{10,11,80},{10,11,224},{11,11,229},{ +11,11,652},{12,11,192},{13,11,146},{142,11,91},{132,11,295},{6,11,619},{7,11,898 +},{7,11,1092},{8,11,485},{18,11,28},{147,11,116},{137,11,51},{6,10,1661},{7,10, +1975},{7,10,2009},{135,10,2011},{5,11,309},{140,11,211},{5,0,87},{7,0,313},{7,0, +1103},{10,0,208},{10,0,582},{11,0,389},{11,0,813},{12,0,385},{13,0,286},{14,0, +124},{146,0,108},{5,11,125},{8,11,77},{138,11,15},{132,0,267},{133,0,703},{137, +11,155},{133,11,439},{11,11,164},{140,11,76},{5,10,89},{7,10,1915},{9,0,496},{9, +10,185},{9,10,235},{10,10,64},{10,10,270},{10,10,403},{10,10,469},{10,10,529},{ +10,10,590},{11,10,140},{11,10,860},{13,10,1},{13,10,422},{14,10,341},{14,10,364} +,{17,10,93},{18,10,113},{19,10,97},{147,10,113},{133,10,695},{135,0,1121},{5,10, +6},{6,10,183},{7,10,680},{7,10,978},{7,10,1013},{7,10,1055},{12,10,230},{13,10, +172},{146,10,29},{4,11,8},{7,11,1152},{7,11,1153},{7,11,1715},{9,11,374},{10,11, +478},{139,11,648},{135,11,1099},{6,10,29},{139,10,63},{4,0,561},{10,0,249},{139, +0,209},{132,0,760},{7,11,799},{138,11,511},{136,11,87},{9,0,154},{140,0,485},{ +136,0,255},{132,0,323},{140,0,419},{132,10,311},{134,10,1740},{4,0,368},{135,0, +641},{7,10,170},{8,10,90},{8,10,177},{8,10,415},{11,10,714},{142,10,281},{4,11, +69},{5,11,122},{9,11,656},{138,11,464},{5,11,849},{134,11,1633},{8,0,522},{142,0 +,328},{11,10,91},{13,10,129},{15,10,101},{145,10,125},{4,10,494},{6,10,74},{7,0, +562},{7,10,44},{8,0,551},{11,11,499},{12,10,17},{15,10,5},{148,10,11},{4,10,276} +,{133,10,296},{9,0,92},{147,0,91},{4,10,7},{5,10,90},{5,10,158},{6,10,542},{7,10 +,221},{7,10,1574},{9,10,490},{10,10,540},{11,10,443},{139,10,757},{6,0,525},{6,0 +,1976},{8,0,806},{9,0,876},{140,0,284},{5,11,859},{7,10,588},{7,11,1160},{8,11, +107},{9,10,175},{9,11,291},{9,11,439},{10,10,530},{10,11,663},{11,11,609},{140, +11,197},{7,11,168},{13,11,196},{141,11,237},{139,0,958},{133,0,594},{135,10,580} +,{7,10,88},{136,10,627},{5,10,872},{6,0,479},{6,0,562},{6,10,57},{7,0,1060},{7, +10,471},{9,10,447},{9,10,454},{141,0,6},{136,11,413},{145,11,19},{4,11,117},{6, +11,372},{7,11,1905},{142,11,323},{4,11,722},{139,11,471},{5,10,31},{6,10,614},{ +145,0,61},{8,10,330},{140,10,477},{7,10,1200},{138,10,460},{6,10,424},{135,10, +1866},{6,0,1641},{136,0,820},{6,0,1556},{134,0,1618},{9,11,5},{12,11,216},{12,11 +,294},{12,11,298},{12,11,400},{12,11,518},{13,11,229},{143,11,139},{15,11,155},{ +144,11,79},{4,0,302},{135,0,1766},{5,10,13},{134,10,142},{6,0,148},{7,0,1313},{7 +,10,116},{8,10,322},{8,10,755},{9,10,548},{10,10,714},{11,10,884},{141,10,324},{ +137,0,676},{9,11,88},{139,11,270},{5,11,12},{7,11,375},{137,11,438},{134,0,1674} +,{7,10,1472},{135,10,1554},{7,10,1071},{7,10,1541},{7,10,1767},{7,10,1806},{11,0 +,178},{11,10,162},{11,10,242},{12,10,605},{15,10,26},{144,10,44},{6,0,389},{7,0, +149},{9,0,142},{138,0,94},{140,11,71},{145,10,115},{6,0,8},{7,0,1881},{8,0,91},{ +11,11,966},{12,11,287},{13,11,342},{13,11,402},{15,11,110},{143,11,163},{4,11, +258},{136,11,639},{6,11,22},{7,11,903},{138,11,577},{133,11,681},{135,10,1111},{ +135,11,1286},{8,10,1},{9,0,112},{138,10,326},{5,10,488},{6,10,527},{7,10,489},{7 +,10,1636},{8,10,121},{8,10,144},{8,10,359},{9,10,193},{9,10,241},{9,10,336},{9, +10,882},{11,10,266},{11,10,372},{11,10,944},{12,10,401},{140,10,641},{4,11,664}, +{133,11,804},{6,0,747},{134,0,1015},{135,0,1746},{9,10,31},{10,10,244},{10,10, +699},{12,10,149},{141,10,497},{133,10,377},{135,0,24},{5,11,32},{6,0,1352},{145, +10,101},{7,0,1530},{10,0,158},{13,0,13},{13,0,137},{13,0,258},{14,0,111},{14,0, +225},{14,0,253},{14,0,304},{14,0,339},{14,0,417},{146,0,33},{4,0,503},{135,0, +1661},{5,0,130},{6,0,845},{7,0,1314},{9,0,610},{10,0,718},{11,0,601},{11,0,819}, +{11,0,946},{140,0,536},{10,0,149},{11,0,280},{142,0,336},{134,0,1401},{135,0, +1946},{8,0,663},{144,0,8},{134,0,1607},{135,10,2023},{4,11,289},{7,11,629},{7,11 +,1698},{7,11,1711},{140,11,215},{6,11,450},{136,11,109},{10,0,882},{10,0,883},{ +10,0,914},{138,0,928},{133,10,843},{136,11,705},{132,10,554},{133,10,536},{5,0, +417},{9,10,79},{11,10,625},{145,10,7},{7,11,1238},{142,11,37},{4,0,392},{135,0, +1597},{4,10,424},{5,0,433},{9,0,633},{139,0,629},{7,10,336},{136,10,785},{134,11 +,355},{6,0,234},{7,0,769},{9,0,18},{138,0,358},{4,10,896},{134,10,1777},{138,11, +323},{7,0,140},{7,0,1950},{8,0,680},{11,0,817},{147,0,88},{7,0,1222},{138,0,386} +,{139,11,908},{11,0,249},{12,0,313},{16,0,66},{145,0,26},{134,0,5},{7,10,750},{9 +,10,223},{11,10,27},{11,10,466},{12,10,624},{14,10,265},{146,10,61},{134,11,26}, +{134,0,1216},{5,0,963},{134,0,1773},{4,11,414},{5,11,467},{9,11,654},{10,11,451} +,{12,11,59},{141,11,375},{135,11,17},{4,10,603},{133,10,661},{4,10,11},{6,10,128 +},{7,10,231},{7,10,1533},{138,10,725},{135,11,955},{7,0,180},{8,0,509},{136,0, +792},{132,10,476},{132,0,1002},{133,11,538},{135,10,1807},{132,0,931},{7,0,943}, +{11,0,614},{140,0,747},{135,0,1837},{9,10,20},{10,10,324},{10,10,807},{139,10, +488},{134,0,641},{6,11,280},{10,11,502},{11,11,344},{140,11,38},{5,11,45},{7,11, +1161},{11,11,448},{11,11,880},{13,11,139},{13,11,407},{15,11,16},{17,11,95},{18, +11,66},{18,11,88},{18,11,123},{149,11,7},{9,0,280},{138,0,134},{22,0,22},{23,0,5 +},{151,0,29},{136,11,777},{4,0,90},{4,11,410},{5,0,545},{7,0,754},{7,11,521},{9, +0,186},{10,0,72},{10,0,782},{11,0,577},{11,0,610},{11,0,960},{12,0,354},{12,0, +362},{140,0,595},{135,11,1778},{5,10,112},{6,10,103},{134,10,150},{138,10,356},{ +132,0,742},{7,0,151},{9,0,329},{139,0,254},{8,0,853},{8,0,881},{8,0,911},{8,0, +912},{10,0,872},{12,0,741},{12,0,742},{152,0,18},{4,11,573},{136,11,655},{6,0, +921},{134,0,934},{9,0,187},{10,0,36},{11,0,1016},{17,0,44},{146,0,64},{7,0,833}, +{136,0,517},{4,0,506},{5,0,295},{135,0,1680},{4,10,708},{8,10,15},{9,10,50},{9, +10,386},{11,10,18},{11,10,529},{140,10,228},{4,10,563},{7,0,251},{7,0,1701},{7, +10,592},{7,10,637},{7,10,770},{8,0,436},{8,10,463},{9,10,60},{9,10,335},{9,10, +904},{10,10,73},{11,10,434},{12,10,585},{13,10,331},{18,10,110},{148,10,60},{132 +,10,502},{136,0,584},{6,10,347},{138,10,161},{7,0,987},{7,11,899},{9,0,688},{10, +0,522},{11,0,788},{12,0,137},{12,0,566},{14,0,9},{14,0,24},{14,0,64},{142,11,325 +},{4,0,214},{5,0,500},{5,10,102},{6,10,284},{7,10,1079},{7,10,1423},{7,10,1702}, +{8,10,470},{9,10,554},{9,10,723},{139,10,333},{7,10,246},{135,10,840},{6,10,10}, +{8,10,571},{9,10,739},{143,10,91},{133,10,626},{146,0,195},{134,0,1775},{7,0,389 +},{7,0,700},{7,0,940},{8,0,514},{9,0,116},{9,0,535},{10,0,118},{11,0,107},{11,0, +148},{11,0,922},{12,0,254},{12,0,421},{142,0,238},{5,10,18},{6,10,526},{13,10,24 +},{13,10,110},{19,10,5},{147,10,44},{132,0,743},{4,10,309},{5,10,462},{7,10,970} +,{7,10,1097},{139,0,292},{22,10,30},{150,10,33},{139,11,338},{135,11,1598},{7,0, +1283},{9,0,227},{11,0,325},{11,0,408},{14,0,180},{146,0,47},{4,0,953},{6,0,1805} +,{6,0,1814},{6,0,1862},{140,0,774},{6,11,611},{135,11,1733},{135,11,1464},{5,0, +81},{7,0,146},{7,0,1342},{8,0,53},{8,0,561},{8,0,694},{8,0,754},{9,0,115},{9,0, +179},{9,0,894},{10,0,462},{10,0,813},{11,0,230},{11,0,657},{11,0,699},{11,0,748} +,{12,0,119},{12,0,200},{12,0,283},{142,0,273},{5,0,408},{6,0,789},{6,0,877},{6,0 +,1253},{6,0,1413},{137,0,747},{134,10,1704},{135,11,663},{6,0,1910},{6,0,1915},{ +6,0,1923},{9,0,913},{9,0,928},{9,0,950},{9,0,954},{9,0,978},{9,0,993},{12,0,812} +,{12,0,819},{12,0,831},{12,0,833},{12,0,838},{12,0,909},{12,0,928},{12,0,931},{ +12,0,950},{15,0,186},{15,0,187},{15,0,195},{15,0,196},{15,0,209},{15,0,215},{15, +0,236},{15,0,241},{15,0,249},{15,0,253},{18,0,180},{18,0,221},{18,0,224},{18,0, +227},{18,0,229},{149,0,60},{7,0,1826},{135,0,1938},{5,10,86},{7,10,743},{9,10,85 +},{10,10,281},{10,10,432},{11,0,490},{12,10,251},{13,10,118},{14,10,378},{146,0, +143},{5,10,524},{133,10,744},{141,11,442},{10,10,107},{140,10,436},{135,11,503}, +{134,0,1162},{132,10,927},{7,0,30},{8,0,86},{8,0,315},{8,0,700},{9,0,576},{9,0, +858},{10,0,414},{11,0,310},{11,0,888},{11,0,904},{12,0,361},{12,10,670},{13,0, +248},{13,0,371},{14,0,142},{146,10,94},{134,0,721},{4,11,113},{5,11,163},{5,11, +735},{7,10,1149},{7,11,1009},{9,10,156},{9,11,9},{9,11,771},{12,11,90},{13,11, +138},{13,11,410},{143,11,128},{138,0,839},{133,10,778},{137,0,617},{133,10,502}, +{8,10,196},{10,10,283},{139,10,406},{6,0,428},{7,0,524},{8,0,169},{8,0,234},{9,0 +,480},{138,0,646},{133,10,855},{134,0,1648},{7,0,1205},{138,0,637},{4,11,935},{5 +,11,823},{135,0,1596},{5,11,269},{7,11,434},{7,11,891},{8,11,339},{9,11,702},{11 +,11,594},{11,11,718},{145,11,100},{7,11,878},{9,11,485},{141,11,264},{4,0,266},{ +6,11,1713},{8,0,4},{9,0,39},{10,0,166},{11,0,918},{12,0,635},{20,0,10},{22,0,27} +,{22,0,43},{150,0,52},{7,10,1400},{9,10,446},{138,10,45},{135,11,900},{132,0,862 +},{134,0,1554},{135,11,1033},{19,0,16},{147,11,16},{135,11,1208},{7,0,157},{136, +0,279},{6,0,604},{136,0,391},{13,10,455},{15,10,99},{15,10,129},{144,10,68},{135 +,10,172},{7,0,945},{11,0,713},{139,0,744},{4,0,973},{10,0,877},{10,0,937},{10,0, +938},{140,0,711},{139,0,1022},{132,10,568},{142,11,143},{4,0,567},{4,10,732},{ +137,0,859},{7,0,1846},{136,0,628},{136,10,733},{133,0,762},{4,10,428},{135,10, +1789},{7,10,2015},{10,0,784},{12,10,665},{141,0,191},{133,0,298},{7,0,633},{7,0, +905},{7,0,909},{7,0,1538},{9,0,767},{140,0,636},{138,10,806},{132,0,795},{139,0, +301},{135,0,1970},{5,11,625},{135,11,1617},{135,11,275},{7,11,37},{8,11,425},{8, +11,693},{9,11,720},{10,11,380},{10,11,638},{11,11,273},{11,11,307},{11,11,473},{ +12,11,61},{143,11,43},{135,11,198},{134,0,1236},{7,0,369},{12,0,644},{12,0,645}, +{144,0,90},{19,0,15},{149,0,27},{6,0,71},{6,10,1623},{6,10,1681},{7,0,845},{8,0, +160},{137,0,318},{134,0,1447},{134,0,1255},{138,0,735},{4,11,168},{136,0,76},{6, +10,1748},{8,10,715},{9,10,802},{10,10,46},{10,10,819},{13,10,308},{14,10,351},{ +14,10,363},{146,10,67},{135,11,91},{4,10,63},{5,10,347},{134,0,474},{133,10,749} +,{138,0,841},{133,10,366},{4,11,225},{134,0,836},{135,0,1622},{135,10,89},{140,0 +,735},{134,0,1601},{138,11,145},{6,0,1390},{137,0,804},{142,0,394},{6,11,15},{7, +11,70},{10,11,240},{147,11,93},{6,0,96},{135,0,1426},{4,0,651},{133,0,289},{7,10 +,977},{7,11,956},{7,11,1157},{7,11,1506},{7,11,1606},{7,11,1615},{7,11,1619},{7, +11,1736},{7,11,1775},{8,11,590},{9,11,324},{9,11,736},{9,11,774},{9,11,776},{9, +11,784},{10,11,567},{10,11,708},{11,11,518},{11,11,613},{11,11,695},{11,11,716}, +{11,11,739},{11,11,770},{11,11,771},{11,11,848},{11,11,857},{11,11,931},{11,11, +947},{12,11,326},{12,11,387},{12,11,484},{12,11,528},{12,11,552},{12,11,613},{13 +,11,189},{13,11,256},{13,11,340},{13,11,432},{13,11,436},{13,11,440},{13,11,454} +,{14,11,174},{14,11,220},{14,11,284},{14,11,390},{145,11,121},{7,0,688},{8,0,35} +,{9,0,511},{10,0,767},{147,0,118},{134,0,667},{4,0,513},{5,10,824},{133,10,941}, +{7,10,440},{8,10,230},{139,10,106},{134,0,2034},{135,11,1399},{143,11,66},{135, +11,1529},{4,11,145},{6,11,176},{7,11,395},{9,11,562},{144,11,28},{132,11,501},{ +132,0,704},{134,0,1524},{6,11,464},{135,0,1078},{6,11,509},{10,11,82},{20,11,91} +,{151,11,13},{4,0,720},{133,0,306},{133,0,431},{4,10,914},{5,10,800},{5,10,852}, +{135,0,1196},{135,11,1189},{10,0,54},{141,10,115},{7,10,564},{142,10,168},{4,10, +918},{5,0,464},{5,10,876},{6,0,236},{7,0,696},{7,0,914},{7,0,1108},{7,0,1448},{9 +,0,15},{9,0,564},{10,0,14},{12,0,565},{13,0,449},{14,0,53},{15,0,13},{16,0,64},{ +145,0,41},{6,0,1418},{134,10,1764},{4,10,92},{133,10,274},{134,0,907},{4,11,114} +,{8,10,501},{9,11,492},{13,11,462},{142,11,215},{4,11,77},{5,11,361},{6,11,139}, +{6,11,401},{6,11,404},{7,11,413},{7,11,715},{7,11,1716},{11,11,279},{12,11,179}, +{12,11,258},{13,11,244},{142,11,358},{6,0,1767},{12,0,194},{145,0,107},{134,11, +1717},{5,10,743},{142,11,329},{4,10,49},{7,10,280},{135,10,1633},{5,0,840},{7,11 +,1061},{8,11,82},{11,11,250},{12,11,420},{141,11,184},{135,11,724},{134,0,900},{ +136,10,47},{134,0,1436},{144,11,0},{5,10,272},{5,10,908},{5,10,942},{6,0,675},{7 +,0,1008},{7,0,1560},{8,10,197},{9,0,642},{9,10,47},{11,0,236},{11,10,538},{11,10 +,742},{142,0,193},{4,0,68},{5,0,628},{5,0,634},{6,0,386},{7,0,794},{8,0,273},{9, +0,563},{10,0,105},{10,0,171},{11,0,94},{139,0,354},{135,10,1911},{137,10,891},{4 +,0,95},{6,0,1297},{6,0,1604},{7,0,416},{139,0,830},{6,11,513},{135,11,1052},{7,0 +,731},{13,0,20},{143,0,11},{137,11,899},{10,0,850},{140,0,697},{4,0,662},{7,11, +1417},{12,11,382},{17,11,48},{152,11,12},{133,0,736},{132,0,861},{4,10,407},{132 +,10,560},{141,10,490},{6,11,545},{7,11,565},{7,11,1669},{10,11,114},{11,11,642}, +{140,11,618},{6,0,871},{134,0,1000},{5,0,864},{5,11,5},{10,0,648},{11,0,671},{ +143,0,46},{133,0,928},{4,10,475},{11,0,90},{11,10,35},{13,0,7},{13,10,71},{13,10 +,177},{142,10,422},{136,0,332},{135,11,192},{134,0,1055},{136,11,763},{11,0,986} +,{140,0,682},{7,0,76},{8,0,44},{9,0,884},{10,0,580},{11,0,399},{11,0,894},{143,0 +,122},{135,11,1237},{135,10,636},{6,10,222},{7,10,1620},{8,10,409},{9,10,693},{ +139,0,300},{4,11,87},{5,11,250},{10,11,601},{13,11,298},{13,11,353},{141,11,376} +,{5,0,518},{10,0,340},{11,0,175},{149,0,16},{140,0,771},{6,0,1108},{137,0,831},{ +132,0,836},{135,0,1852},{4,0,957},{6,0,1804},{8,0,842},{8,0,843},{8,0,851},{8,0, +855},{140,0,767},{135,11,814},{4,11,57},{7,11,1195},{7,11,1438},{7,11,1548},{7, +11,1835},{7,11,1904},{9,11,757},{10,11,604},{139,11,519},{133,10,882},{138,0,246 +},{4,0,934},{5,0,202},{7,11,1897},{8,0,610},{12,11,290},{13,11,80},{13,11,437},{ +145,11,74},{8,0,96},{9,0,36},{10,0,607},{10,0,804},{10,0,832},{11,0,423},{11,0, +442},{12,0,309},{14,0,199},{15,0,90},{145,0,110},{132,10,426},{6,10,58},{7,0,654 +},{7,10,745},{7,10,1969},{8,0,240},{8,10,675},{9,10,479},{9,10,731},{10,10,330}, +{10,10,593},{10,10,817},{11,10,32},{11,10,133},{11,10,221},{145,10,68},{9,0,13}, +{9,0,398},{9,0,727},{10,0,75},{10,0,184},{10,0,230},{10,0,564},{10,0,569},{11,0, +973},{12,0,70},{12,0,189},{13,0,57},{141,0,257},{4,11,209},{135,11,902},{7,0,391 +},{137,10,538},{134,0,403},{6,11,303},{7,11,335},{7,11,1437},{7,11,1668},{8,11, +553},{8,11,652},{8,11,656},{9,11,558},{11,11,743},{149,11,18},{132,11,559},{11,0 +,75},{142,0,267},{6,0,815},{141,11,2},{141,0,366},{137,0,631},{133,11,1017},{5,0 +,345},{135,0,1016},{133,11,709},{134,11,1745},{133,10,566},{6,10,48},{7,0,952},{ +9,10,139},{10,10,399},{11,10,469},{12,10,634},{141,10,223},{133,0,673},{7,11,8}, +{8,11,206},{137,0,850},{6,0,662},{149,0,35},{4,0,287},{133,0,1018},{6,10,114},{7 +,10,1224},{7,10,1556},{136,10,3},{8,10,576},{137,10,267},{4,0,884},{5,0,34},{10, +0,724},{12,0,444},{13,0,354},{18,0,32},{23,0,24},{23,0,31},{152,0,5},{133,10,933 +},{132,11,776},{138,0,151},{136,0,427},{134,0,382},{132,0,329},{9,0,846},{10,0, +827},{138,11,33},{7,11,1297},{9,0,279},{10,0,407},{14,0,84},{150,0,18},{136,11, +406},{132,0,906},{136,0,366},{134,0,843},{134,0,1443},{135,0,1372},{138,0,992},{ +4,0,123},{5,0,605},{7,0,1509},{136,0,36},{132,0,649},{8,11,175},{10,11,168},{138 +,11,573},{133,0,767},{134,0,1018},{135,11,1305},{12,10,30},{13,10,148},{14,10,87 +},{14,10,182},{16,10,42},{148,10,70},{134,11,607},{4,0,273},{5,0,658},{133,0,995 +},{6,0,72},{139,11,174},{7,10,56},{7,10,1989},{8,10,337},{8,10,738},{9,10,600},{ +10,0,483},{12,0,368},{13,10,447},{142,10,92},{5,11,784},{138,10,666},{135,0,1345 +},{139,11,882},{134,0,1293},{133,0,589},{134,0,1988},{5,0,117},{6,0,514},{6,0, +541},{7,0,1164},{7,0,1436},{8,0,220},{8,0,648},{10,0,688},{139,0,560},{136,0,379 +},{5,0,686},{7,10,866},{135,10,1163},{132,10,328},{9,11,14},{9,11,441},{10,11, +306},{139,11,9},{4,10,101},{135,10,1171},{5,10,833},{136,10,744},{5,11,161},{7, +11,839},{135,11,887},{7,0,196},{10,0,765},{11,0,347},{11,0,552},{11,0,790},{12,0 +,263},{13,0,246},{13,0,270},{13,0,395},{14,0,176},{14,0,190},{14,0,398},{14,0, +412},{15,0,32},{15,0,63},{16,0,88},{147,0,105},{6,10,9},{6,10,397},{7,10,53},{7, +10,1742},{10,10,632},{11,10,828},{140,10,146},{5,0,381},{135,0,1792},{134,0,1452 +},{135,11,429},{8,0,367},{10,0,760},{14,0,79},{20,0,17},{152,0,0},{7,0,616},{138 +,0,413},{11,10,417},{12,10,223},{140,10,265},{7,11,1611},{13,11,14},{15,11,44},{ +19,11,13},{148,11,76},{135,0,1229},{6,0,120},{7,0,1188},{7,0,1710},{8,0,286},{9, +0,667},{11,0,592},{139,0,730},{135,11,1814},{135,0,1146},{4,10,186},{5,10,157},{ +8,10,168},{138,10,6},{4,0,352},{135,0,687},{4,0,192},{5,0,49},{6,0,200},{6,0,293 +},{6,0,1696},{135,0,1151},{133,10,875},{5,10,773},{5,10,991},{6,10,1635},{134,10 +,1788},{7,10,111},{136,10,581},{6,0,935},{134,0,1151},{134,0,1050},{132,0,650},{ +132,0,147},{11,0,194},{11,11,194},{12,0,62},{12,0,88},{12,11,62},{140,11,88},{6, +0,339},{135,0,923},{134,10,1747},{7,11,643},{136,11,236},{133,0,934},{7,10,1364} +,{7,10,1907},{141,10,158},{132,10,659},{4,10,404},{135,10,675},{7,11,581},{9,11, +644},{137,11,699},{13,0,211},{14,0,133},{14,0,204},{15,0,64},{15,0,69},{15,0,114 +},{16,0,10},{19,0,23},{19,0,35},{19,0,39},{19,0,51},{19,0,71},{19,0,75},{152,0, +15},{133,10,391},{5,11,54},{135,11,1513},{5,10,540},{6,10,1697},{7,0,222},{136,0 +,341},{134,10,78},{132,11,744},{136,0,293},{137,11,701},{7,11,930},{10,11,402},{ +10,11,476},{13,11,452},{18,11,55},{147,11,104},{132,0,637},{133,10,460},{8,11,50 +},{137,11,624},{132,11,572},{134,0,1159},{4,10,199},{139,10,34},{134,0,847},{134 +,10,388},{6,11,43},{7,11,38},{8,11,248},{9,11,504},{138,11,513},{4,10,511},{6,10 +,608},{9,0,683},{9,10,333},{10,10,602},{11,10,441},{11,10,723},{11,10,976},{140, +10,357},{9,0,867},{138,0,837},{6,0,944},{135,11,326},{135,0,1809},{5,10,938},{7, +11,783},{136,10,707},{133,11,766},{133,11,363},{6,0,170},{7,0,1080},{8,0,395},{8 +,0,487},{141,0,147},{6,11,258},{140,11,409},{4,0,535},{5,11,249},{8,0,618},{148, +11,82},{6,0,1379},{149,11,15},{135,0,1625},{150,0,23},{5,11,393},{6,11,378},{7, +11,1981},{9,11,32},{9,11,591},{10,11,685},{10,11,741},{142,11,382},{133,11,788}, +{7,11,1968},{10,11,19},{139,11,911},{7,11,1401},{135,11,1476},{4,11,61},{5,11,58 +},{5,11,171},{5,11,635},{5,11,683},{5,11,700},{6,11,291},{6,11,566},{7,11,1650}, +{11,11,523},{12,11,273},{12,11,303},{15,11,39},{143,11,111},{6,10,469},{7,10, +1709},{138,10,515},{4,0,778},{134,11,589},{132,0,46},{5,0,811},{6,0,1679},{6,0, +1714},{135,0,2032},{7,0,1458},{9,0,407},{11,0,15},{12,0,651},{149,0,37},{4,10, +500},{135,0,938},{6,0,34},{7,0,69},{7,0,1089},{7,0,1281},{8,0,708},{8,0,721},{9, +0,363},{148,0,98},{10,11,231},{147,11,124},{7,11,726},{152,11,9},{5,10,68},{134, +10,383},{136,11,583},{4,11,917},{133,11,1005},{11,10,216},{139,10,340},{135,11, +1675},{8,0,441},{10,0,314},{143,0,3},{132,11,919},{4,10,337},{6,10,353},{7,10, +1934},{8,10,488},{137,10,429},{7,0,889},{7,10,1795},{8,10,259},{9,10,135},{9,10, +177},{9,10,860},{10,10,825},{11,10,115},{11,10,370},{11,10,405},{11,10,604},{12, +10,10},{12,10,667},{12,10,669},{13,10,76},{14,10,310},{15,10,76},{15,10,147},{ +148,10,23},{4,10,15},{4,11,255},{5,10,22},{5,11,302},{6,10,244},{6,11,132},{7,10 +,40},{7,10,200},{7,10,906},{7,10,1199},{7,11,128},{7,11,283},{7,11,1299},{9,10, +616},{10,10,716},{10,11,52},{10,11,514},{11,10,635},{11,10,801},{11,11,925},{12, +10,458},{13,11,92},{142,11,309},{132,0,462},{137,11,173},{135,10,1735},{5,10,598 +},{7,10,791},{8,0,525},{8,10,108},{137,10,123},{5,0,73},{6,0,23},{134,0,338},{ +132,0,676},{132,10,683},{7,0,725},{8,0,498},{139,0,268},{12,0,21},{151,0,7},{135 +,0,773},{4,10,155},{135,10,1689},{4,0,164},{5,0,730},{5,10,151},{5,10,741},{6,11 +,210},{7,10,498},{7,10,870},{7,10,1542},{12,10,213},{14,10,36},{14,10,391},{17, +10,111},{18,10,6},{18,10,46},{18,10,151},{19,10,36},{20,10,32},{20,10,56},{20,10 +,69},{20,10,102},{21,10,4},{22,10,8},{22,10,10},{22,10,14},{150,10,31},{4,10,624 +},{135,10,1752},{4,0,583},{6,11,588},{9,0,936},{15,0,214},{18,0,199},{152,0,26}, +{4,11,284},{6,11,223},{7,0,1462},{139,0,659},{133,0,220},{139,0,803},{132,0,544} +,{4,10,492},{133,10,451},{16,0,98},{148,0,119},{4,11,218},{7,11,526},{143,11,137 +},{135,10,835},{4,11,270},{5,11,192},{6,11,332},{7,11,1322},{13,10,70},{13,11,9} +,{14,11,104},{142,11,311},{132,10,539},{140,11,661},{5,0,176},{6,0,437},{6,0,564 +},{11,0,181},{141,0,183},{135,0,1192},{6,10,113},{135,10,436},{136,10,718},{135, +10,520},{135,0,1878},{140,11,196},{7,11,379},{8,11,481},{137,11,377},{5,11,1003} +,{6,11,149},{137,11,746},{8,11,262},{9,11,627},{10,11,18},{11,11,214},{11,11,404 +},{11,11,457},{11,11,780},{11,11,849},{11,11,913},{13,11,330},{13,11,401},{142, +11,200},{149,0,26},{136,11,304},{132,11,142},{135,0,944},{4,0,790},{5,0,273},{ +134,0,394},{134,0,855},{4,0,135},{6,0,127},{7,0,1185},{7,0,1511},{8,0,613},{11,0 +,5},{12,0,336},{12,0,495},{12,0,586},{12,0,660},{12,0,668},{14,0,385},{15,0,118} +,{17,0,20},{146,0,98},{6,0,230},{9,0,752},{12,10,610},{13,10,431},{16,10,59},{ +146,0,109},{7,0,1954},{135,11,925},{4,11,471},{5,11,51},{6,11,602},{8,11,484},{ +10,11,195},{140,11,159},{132,10,307},{136,11,688},{132,11,697},{7,11,812},{7,11, +1261},{7,11,1360},{9,11,632},{140,11,352},{5,0,162},{5,10,964},{136,0,68},{4,0, +654},{136,11,212},{4,0,156},{7,0,998},{7,0,1045},{7,0,1860},{9,0,48},{9,0,692},{ +11,0,419},{139,0,602},{133,11,221},{4,11,373},{5,11,283},{6,11,480},{135,11,609} +,{142,11,216},{132,0,240},{6,11,192},{9,11,793},{145,11,55},{4,10,75},{5,10,180} +,{6,10,500},{7,10,58},{7,10,710},{138,10,645},{4,11,132},{5,10,649},{5,11,69},{ +135,11,1242},{6,10,276},{7,10,282},{7,10,879},{7,10,924},{8,10,459},{9,10,599},{ +9,10,754},{11,10,574},{12,10,128},{12,10,494},{13,10,52},{13,10,301},{15,10,30}, +{143,10,132},{132,10,200},{4,11,111},{135,11,302},{9,0,197},{10,0,300},{12,0,473 +},{13,0,90},{141,0,405},{132,11,767},{6,11,42},{7,11,1416},{7,11,1590},{7,11, +2005},{8,11,131},{8,11,466},{9,11,672},{13,11,252},{148,11,103},{8,0,958},{8,0, +999},{10,0,963},{138,0,1001},{135,10,1621},{135,0,858},{4,0,606},{137,11,444},{6 +,11,44},{136,11,368},{139,11,172},{4,11,570},{133,11,120},{139,11,624},{6,10,225 +},{7,0,1978},{8,0,676},{137,10,211},{7,0,972},{8,10,687},{139,0,102},{6,11,227}, +{135,11,1589},{8,10,58},{9,10,724},{11,10,809},{13,10,113},{145,10,72},{4,0,361} +,{133,0,315},{132,0,461},{6,10,345},{135,10,1247},{132,0,472},{8,10,767},{8,10, +803},{9,10,301},{137,10,903},{135,11,1333},{135,11,477},{7,10,1949},{136,10,674} +,{6,0,905},{138,0,747},{133,0,155},{134,10,259},{7,0,163},{8,0,319},{9,0,402},{ +10,0,24},{10,0,681},{11,0,200},{12,0,253},{12,0,410},{142,0,219},{5,0,475},{6,11 +,1667},{7,0,1780},{7,11,2036},{9,0,230},{10,11,600},{11,0,297},{11,0,558},{14,0, +322},{147,0,76},{136,10,254},{6,0,848},{135,0,1956},{6,11,511},{140,11,132},{5, +11,568},{6,11,138},{135,11,1293},{6,0,631},{137,0,838},{149,0,36},{4,11,565},{8, +11,23},{136,11,827},{5,0,944},{134,0,1769},{4,0,144},{4,11,922},{5,11,1023},{6,0 +,842},{134,0,1400},{133,10,248},{9,10,800},{10,10,693},{11,10,482},{11,10,734},{ +139,10,789},{7,11,1002},{139,11,145},{4,10,116},{5,10,95},{5,10,445},{7,10,1688} +,{8,10,29},{9,10,272},{11,10,509},{139,10,915},{14,0,369},{146,0,72},{135,10, +1641},{132,11,740},{133,10,543},{140,11,116},{5,10,181},{6,0,247},{8,10,41},{137 +,0,555},{133,10,657},{136,0,996},{138,10,709},{7,0,189},{8,10,202},{138,10,536}, +{136,11,402},{4,11,716},{141,11,31},{10,0,280},{138,0,797},{9,10,423},{140,10,89 +},{8,10,113},{9,10,877},{10,10,554},{11,10,83},{12,10,136},{147,10,109},{133,10, +976},{4,10,206},{135,0,746},{136,0,526},{139,0,345},{136,0,1017},{8,11,152},{9, +11,53},{9,11,268},{9,11,901},{10,11,518},{10,11,829},{11,11,188},{13,11,74},{14, +11,46},{15,11,17},{15,11,33},{17,11,40},{18,11,36},{19,11,20},{22,11,1},{152,11, +2},{133,11,736},{136,11,532},{5,0,428},{138,0,651},{135,11,681},{135,0,1162},{7, +0,327},{8,10,226},{10,10,537},{11,10,570},{11,10,605},{11,10,799},{11,10,804},{ +12,10,85},{12,10,516},{12,10,623},{12,11,677},{13,0,230},{13,10,361},{14,10,77}, +{14,10,78},{17,0,113},{147,10,110},{4,0,792},{4,10,769},{7,0,1717},{138,0,546},{ +4,11,684},{136,11,384},{132,10,551},{134,0,1203},{9,10,57},{9,10,459},{10,10,425 +},{11,10,119},{12,10,184},{12,10,371},{13,10,358},{145,10,51},{5,0,672},{5,10, +814},{8,10,10},{9,10,421},{9,10,729},{10,10,609},{139,10,689},{138,0,189},{134, +10,624},{7,11,110},{7,11,188},{8,11,290},{8,11,591},{9,11,382},{9,11,649},{11,11 +,71},{11,11,155},{11,11,313},{12,11,5},{13,11,325},{142,11,287},{133,0,99},{6,0, +1053},{135,0,298},{7,11,360},{7,11,425},{9,11,66},{9,11,278},{138,11,644},{4,0, +397},{136,0,555},{137,10,269},{132,10,528},{4,11,900},{133,11,861},{5,11,254},{6 +,0,1157},{7,11,985},{136,11,73},{7,11,1959},{136,11,683},{12,0,398},{20,0,39},{ +21,0,11},{150,0,41},{4,0,485},{7,0,353},{135,0,1523},{6,0,366},{7,0,1384},{135,0 +,1601},{138,0,787},{137,0,282},{5,10,104},{6,10,173},{135,10,1631},{139,11,146}, +{4,0,157},{133,0,471},{134,0,941},{132,11,725},{7,0,1336},{8,10,138},{8,10,342}, +{9,10,84},{10,10,193},{11,10,883},{140,10,359},{134,11,196},{136,0,116},{133,11, +831},{134,0,787},{134,10,95},{6,10,406},{10,10,409},{10,10,447},{11,10,44},{140, +10,100},{5,0,160},{7,0,363},{7,0,589},{10,0,170},{141,0,55},{134,0,1815},{132,0, +866},{4,11,321},{6,0,889},{6,0,1067},{6,0,1183},{134,11,569},{5,11,848},{134,11, +66},{4,11,36},{6,10,1636},{7,11,1387},{10,11,205},{11,11,755},{141,11,271},{132, +0,689},{4,10,282},{7,10,1034},{9,0,820},{11,10,398},{11,10,634},{12,10,1},{12,10 +,79},{12,10,544},{14,10,237},{17,10,10},{146,10,20},{4,0,108},{7,0,804},{139,0, +498},{132,11,887},{6,0,1119},{135,11,620},{6,11,165},{138,11,388},{5,0,244},{5, +10,499},{6,10,476},{7,10,600},{7,10,888},{135,10,1096},{140,0,609},{135,0,1005}, +{4,0,412},{133,0,581},{4,11,719},{135,11,155},{7,10,296},{7,10,596},{8,10,560},{ +8,10,586},{9,10,612},{11,10,304},{12,10,46},{13,10,89},{14,10,112},{145,10,122}, +{4,0,895},{133,0,772},{142,11,307},{135,0,1898},{4,0,926},{133,0,983},{4,11,353} +,{6,11,146},{6,11,1789},{7,11,288},{7,11,990},{7,11,1348},{9,11,665},{9,11,898}, +{11,11,893},{142,11,212},{132,0,538},{133,11,532},{6,0,294},{7,0,1267},{8,0,624} +,{141,0,496},{4,11,45},{7,0,1325},{135,11,1257},{138,0,301},{7,10,1599},{7,10, +1723},{8,10,79},{8,10,106},{8,10,190},{8,10,302},{8,10,383},{8,10,713},{9,0,298} +,{9,10,119},{9,10,233},{9,10,419},{9,10,471},{10,10,181},{10,10,406},{11,10,57}, +{11,10,85},{11,10,120},{11,10,177},{11,10,296},{11,10,382},{11,10,454},{11,10, +758},{11,10,999},{12,0,291},{12,10,27},{12,10,131},{12,10,245},{12,10,312},{12, +10,446},{12,10,454},{13,0,276},{13,10,98},{13,10,426},{13,10,508},{14,0,6},{14, +10,163},{14,10,272},{14,10,277},{14,10,370},{15,10,95},{15,10,138},{15,10,167},{ +17,0,18},{17,10,38},{20,10,96},{149,0,32},{132,0,757},{134,0,1263},{4,0,820},{ +134,10,1759},{133,0,722},{136,11,816},{138,10,372},{145,10,16},{134,0,1039},{4,0 +,991},{134,0,2028},{133,10,258},{7,0,1875},{139,0,124},{6,11,559},{6,11,1691},{ +135,11,586},{5,0,324},{7,0,881},{8,10,134},{9,10,788},{140,10,438},{7,11,1823},{ +139,11,693},{6,0,1348},{134,0,1545},{134,0,911},{132,0,954},{7,10,1948},{7,10, +2004},{8,0,329},{136,0,414},{5,0,517},{6,10,439},{7,10,780},{135,10,1040},{132,0 +,816},{5,10,1},{6,10,81},{138,10,520},{5,10,482},{8,10,98},{9,0,713},{10,0,222}, +{10,10,700},{10,10,822},{11,10,302},{11,10,778},{12,10,50},{12,10,127},{12,10, +396},{13,10,62},{13,10,328},{14,10,122},{147,10,72},{137,0,33},{5,10,2},{7,10, +1494},{136,10,589},{6,10,512},{7,10,797},{8,10,253},{9,10,77},{10,10,1},{10,10, +129},{10,10,225},{10,11,108},{11,10,118},{11,10,226},{11,10,251},{11,10,430},{11 +,10,701},{11,10,974},{11,10,982},{11,11,116},{12,10,64},{12,10,260},{12,10,488}, +{140,10,690},{134,11,456},{133,11,925},{5,0,150},{7,0,106},{7,0,774},{8,0,603},{ +9,0,593},{9,0,634},{10,0,44},{10,0,173},{11,0,462},{11,0,515},{13,0,216},{13,0, +288},{142,0,400},{137,10,347},{5,0,748},{134,0,553},{12,0,108},{141,0,291},{4,10 +,12},{7,0,420},{7,10,522},{7,10,809},{8,10,797},{141,10,88},{6,11,193},{7,11,240 +},{7,11,1682},{10,11,51},{10,11,640},{11,11,410},{13,11,82},{14,11,247},{14,11, +331},{142,11,377},{133,10,528},{135,0,1777},{4,0,493},{144,0,55},{136,11,633},{ +139,0,81},{6,0,980},{136,0,321},{148,10,109},{5,10,266},{9,10,290},{9,10,364},{ +10,10,293},{11,10,606},{142,10,45},{6,0,568},{7,0,112},{7,0,1804},{8,0,362},{8,0 +,410},{8,0,830},{9,0,514},{11,0,649},{142,0,157},{4,0,74},{6,0,510},{6,10,594},{ +9,10,121},{10,10,49},{10,10,412},{139,10,834},{134,0,838},{136,10,748},{132,10, +466},{132,0,625},{135,11,1443},{4,11,237},{135,11,514},{9,10,378},{141,10,162},{ +6,0,16},{6,0,158},{7,0,43},{7,0,129},{7,0,181},{8,0,276},{8,0,377},{10,0,523},{ +11,0,816},{12,0,455},{13,0,303},{142,0,135},{135,0,281},{4,0,1},{7,0,1143},{7,0, +1463},{8,0,61},{9,0,207},{9,0,390},{9,0,467},{139,0,836},{6,11,392},{7,11,65},{ +135,11,2019},{132,10,667},{4,0,723},{5,0,895},{7,0,1031},{8,0,199},{8,0,340},{9, +0,153},{9,0,215},{10,0,21},{10,0,59},{10,0,80},{10,0,224},{10,0,838},{11,0,229}, +{11,0,652},{12,0,192},{13,0,146},{142,0,91},{132,0,295},{137,0,51},{9,11,222},{ +10,11,43},{139,11,900},{5,0,309},{140,0,211},{5,0,125},{8,0,77},{138,0,15},{136, +11,604},{138,0,789},{4,10,39},{5,0,173},{7,10,1843},{8,10,407},{11,10,144},{140, +10,523},{138,11,265},{133,0,439},{132,10,510},{7,0,648},{7,0,874},{7,10,1980},{ +10,10,487},{10,10,809},{11,0,164},{12,0,76},{146,0,9},{12,0,111},{13,10,260},{14 +,0,294},{18,10,63},{147,0,45},{133,11,549},{134,10,570},{4,0,8},{7,0,1152},{7,0, +1153},{7,0,1715},{9,0,374},{10,0,478},{139,0,648},{135,0,1099},{5,0,575},{6,0, +354},{135,0,701},{7,11,36},{8,11,201},{136,11,605},{4,10,787},{136,11,156},{6,0, +518},{149,11,13},{140,11,224},{134,0,702},{132,10,516},{5,11,724},{10,11,305},{ +11,11,151},{12,11,33},{12,11,121},{12,11,381},{17,11,3},{17,11,27},{17,11,78},{ +18,11,18},{19,11,54},{149,11,5},{4,11,523},{5,11,638},{8,0,87},{11,10,887},{14, +10,365},{142,10,375},{138,0,438},{136,10,821},{135,11,1908},{6,11,242},{7,11,227 +},{7,11,1581},{8,11,104},{9,11,113},{9,11,220},{9,11,427},{10,11,74},{10,11,239} +,{11,11,579},{11,11,1023},{13,11,4},{13,11,204},{13,11,316},{18,11,95},{148,11, +86},{4,0,69},{5,0,122},{5,0,849},{6,0,1633},{9,0,656},{138,0,464},{4,10,10},{7,0 +,1802},{139,10,786},{135,11,861},{139,0,499},{7,0,476},{7,0,1592},{138,0,87},{ +133,10,684},{4,0,840},{134,10,27},{142,0,283},{6,0,1620},{7,11,1328},{136,11,494 +},{5,0,859},{7,0,1160},{8,0,107},{9,0,291},{9,0,439},{10,0,663},{11,0,609},{140, +0,197},{7,11,1306},{8,11,505},{9,11,482},{10,11,126},{11,11,225},{12,11,347},{12 +,11,449},{13,11,19},{142,11,218},{5,11,268},{10,11,764},{12,11,120},{13,11,39},{ +145,11,127},{145,10,56},{7,11,1672},{10,11,472},{11,11,189},{143,11,51},{6,10, +342},{6,10,496},{8,10,275},{137,10,206},{133,0,600},{4,0,117},{6,0,372},{7,0, +1905},{142,0,323},{4,10,909},{5,10,940},{135,11,1471},{132,10,891},{4,0,722},{ +139,0,471},{4,11,384},{135,11,1022},{132,10,687},{9,0,5},{12,0,216},{12,0,294},{ +12,0,298},{12,0,400},{12,0,518},{13,0,229},{143,0,139},{135,11,1703},{7,11,1602} +,{10,11,698},{12,11,212},{141,11,307},{6,10,41},{141,10,160},{135,11,1077},{9,11 +,159},{11,11,28},{140,11,603},{4,0,514},{7,0,1304},{138,0,477},{134,0,1774},{9,0 +,88},{139,0,270},{5,0,12},{6,10,1718},{7,0,375},{137,0,438},{132,11,515},{136,10 +,778},{8,11,632},{8,11,697},{137,11,854},{6,0,362},{6,0,997},{146,0,51},{7,0,816 +},{7,0,1241},{9,0,283},{9,0,520},{10,0,213},{10,0,307},{10,0,463},{10,0,671},{10 +,0,746},{11,0,401},{11,0,794},{12,0,517},{18,0,107},{147,0,115},{133,10,115},{ +150,11,28},{4,11,136},{133,11,551},{142,10,314},{132,0,258},{6,0,22},{7,0,903},{ +7,0,1963},{8,0,639},{138,0,577},{5,0,681},{5,10,193},{8,0,782},{12,10,178},{13,0 +,130},{145,0,84},{9,11,17},{138,11,291},{7,11,1287},{9,11,44},{10,11,552},{10,11 +,642},{11,11,839},{12,11,274},{12,11,275},{12,11,372},{13,11,91},{142,11,125},{ +135,10,174},{4,0,664},{5,0,804},{139,0,1013},{134,0,942},{6,0,1349},{6,0,1353},{ +6,0,1450},{7,11,1518},{139,11,694},{4,10,122},{5,10,796},{5,10,952},{6,10,1660}, +{6,10,1671},{8,10,567},{9,10,687},{9,10,742},{10,10,686},{11,0,356},{11,10,682}, +{140,10,281},{5,0,32},{6,11,147},{7,11,886},{9,11,753},{138,11,268},{5,10,179},{ +7,10,1095},{135,10,1213},{4,10,66},{7,10,722},{135,10,904},{135,10,352},{9,11, +245},{138,11,137},{4,0,289},{5,11,414},{7,0,629},{7,0,1698},{7,0,1711},{140,0, +215},{6,0,1975},{135,11,1762},{6,0,450},{136,0,109},{141,10,35},{134,11,599},{ +136,0,705},{133,0,664},{134,11,1749},{11,11,402},{12,11,109},{12,11,431},{13,11, +179},{13,11,206},{14,11,175},{14,11,217},{16,11,3},{148,11,53},{135,0,1238},{134 +,11,1627},{132,11,488},{10,10,592},{10,10,753},{12,10,317},{12,10,355},{12,10, +465},{12,10,469},{12,10,560},{12,10,578},{141,0,318},{133,10,564},{132,11,83},{ +140,11,676},{6,0,1872},{6,0,1906},{6,0,1907},{9,0,934},{9,0,956},{9,0,960},{9,0, +996},{12,0,794},{12,0,876},{12,0,880},{12,0,918},{15,0,230},{18,0,234},{18,0,238 +},{21,0,38},{149,0,62},{134,10,556},{134,11,278},{137,0,103},{7,10,544},{8,10, +719},{138,10,61},{4,10,5},{5,10,498},{8,10,637},{137,10,521},{7,0,777},{12,0,229 +},{12,0,239},{12,11,229},{12,11,239},{15,0,12},{143,11,12},{6,0,26},{7,11,388},{ +7,11,644},{139,11,781},{7,11,229},{8,11,59},{9,11,190},{9,11,257},{10,11,378},{ +140,11,191},{133,10,927},{135,10,1441},{4,10,893},{5,10,780},{133,10,893},{4,0, +414},{5,0,467},{9,0,654},{10,0,451},{12,0,59},{141,0,375},{142,0,173},{135,0,17} +,{5,10,238},{135,0,1350},{135,0,955},{4,0,960},{10,0,887},{12,0,753},{18,0,161}, +{18,0,162},{152,0,19},{136,11,344},{6,10,1729},{137,11,288},{132,11,660},{4,0, +217},{4,10,60},{5,0,710},{7,0,760},{7,0,1926},{7,10,1800},{8,10,314},{9,0,428},{ +9,0,708},{9,10,700},{10,0,254},{10,0,296},{10,0,720},{11,0,109},{11,0,255},{11, +10,487},{12,0,165},{12,0,315},{13,0,107},{13,0,203},{14,0,54},{14,0,99},{14,0, +114},{14,0,388},{16,0,85},{17,0,9},{17,0,33},{20,0,25},{20,0,28},{20,0,29},{21,0 +,9},{21,0,10},{21,0,34},{150,0,17},{7,11,1035},{138,11,737},{7,11,690},{9,11,217 +},{9,11,587},{140,11,521},{6,0,919},{7,11,706},{7,11,1058},{138,11,538},{7,10, +1853},{138,10,437},{136,10,419},{6,0,280},{10,0,502},{11,0,344},{140,0,38},{5,0, +45},{7,0,1161},{11,0,448},{11,0,880},{13,0,139},{13,0,407},{15,0,16},{17,0,95},{ +18,0,66},{18,0,88},{18,0,123},{149,0,7},{11,11,92},{11,11,196},{11,11,409},{11, +11,450},{11,11,666},{11,11,777},{12,11,262},{13,11,385},{13,11,393},{15,11,115}, +{16,11,45},{145,11,82},{136,0,777},{134,11,1744},{4,0,410},{5,10,828},{135,0,521 +},{134,0,673},{7,0,1110},{7,0,1778},{7,10,176},{135,10,178},{5,10,806},{7,10, +1976},{7,11,268},{136,11,569},{4,11,733},{9,11,194},{10,11,92},{11,11,198},{12, +11,84},{12,11,87},{13,11,128},{144,11,74},{4,10,51},{5,0,341},{6,10,4},{7,0,1129 +},{7,10,591},{7,10,849},{7,10,951},{7,10,1613},{7,10,1760},{7,10,1988},{9,10,434 +},{10,10,754},{11,0,414},{11,10,25},{139,10,37},{133,10,902},{135,10,928},{135,0 +,787},{132,0,436},{134,10,270},{7,0,1587},{135,0,1707},{6,0,377},{7,0,1025},{9,0 +,613},{145,0,104},{7,11,982},{7,11,1361},{10,11,32},{143,11,56},{139,0,96},{132, +0,451},{132,10,416},{142,10,372},{5,10,152},{5,10,197},{7,10,340},{7,10,867},{7, +11,306},{10,10,548},{10,10,581},{11,10,6},{12,10,3},{12,10,19},{14,10,110},{142, +10,289},{134,0,680},{134,11,609},{7,0,483},{7,10,190},{8,10,28},{8,10,141},{8,10 +,444},{8,10,811},{9,10,468},{11,10,334},{12,10,24},{12,10,386},{140,10,576},{5, +10,757},{138,0,916},{5,10,721},{135,10,1553},{133,11,178},{134,0,937},{132,10, +898},{133,0,739},{147,0,82},{135,0,663},{146,0,128},{5,10,277},{141,10,247},{134 +,0,1087},{132,10,435},{6,11,381},{7,11,645},{7,11,694},{136,11,546},{7,0,503},{ +135,0,1885},{6,0,1965},{8,0,925},{138,0,955},{4,0,113},{5,0,163},{5,0,735},{7,0, +1009},{9,0,9},{9,0,771},{12,0,90},{13,0,138},{13,0,410},{143,0,128},{4,0,324},{ +138,0,104},{5,10,265},{6,10,212},{135,0,460},{133,11,105},{7,11,261},{7,11,1107} +,{7,11,1115},{7,11,1354},{7,11,1588},{7,11,1705},{7,11,1902},{9,11,465},{10,11, +248},{10,11,349},{10,11,647},{11,11,527},{11,11,660},{11,11,669},{12,11,529},{ +141,11,305},{5,11,438},{9,11,694},{12,11,627},{141,11,210},{152,11,11},{4,0,935} +,{133,0,823},{132,10,702},{5,0,269},{5,10,808},{7,0,434},{7,0,891},{7,10,2045},{ +8,0,339},{9,0,702},{11,0,594},{11,0,718},{145,0,100},{7,0,1014},{9,0,485},{141,0 +,264},{134,0,1713},{7,0,1810},{11,0,866},{12,0,103},{12,11,233},{141,0,495},{4,0 +,423},{10,0,949},{138,0,1013},{135,0,900},{8,11,25},{138,11,826},{5,10,166},{8, +10,739},{140,10,511},{134,0,2018},{7,11,1270},{139,11,612},{4,10,119},{5,10,170} +,{5,10,447},{7,10,1708},{7,10,1889},{9,10,357},{9,10,719},{12,10,486},{140,10, +596},{12,0,574},{140,11,574},{132,11,308},{6,0,964},{6,0,1206},{134,0,1302},{4, +10,450},{135,10,1158},{135,11,150},{136,11,649},{14,0,213},{148,0,38},{9,11,45}, +{9,11,311},{141,11,42},{134,11,521},{7,10,1375},{7,10,1466},{138,10,331},{132,10 +,754},{5,11,339},{7,11,1442},{14,11,3},{15,11,41},{147,11,66},{136,11,378},{134, +0,1022},{5,10,850},{136,10,799},{142,0,143},{135,0,2029},{134,11,1628},{8,0,523} +,{150,0,34},{5,0,625},{135,0,1617},{7,0,275},{7,10,238},{7,10,2033},{8,10,120},{ +8,10,188},{8,10,659},{9,10,598},{10,10,466},{12,10,342},{12,10,588},{13,10,503}, +{14,10,246},{143,10,92},{7,0,37},{8,0,425},{8,0,693},{9,0,720},{10,0,380},{10,0, +638},{11,0,273},{11,0,473},{12,0,61},{143,0,43},{135,11,829},{135,0,1943},{132,0 +,765},{5,11,486},{135,11,1349},{7,11,1635},{8,11,17},{10,11,217},{138,11,295},{4 +,10,201},{7,10,1744},{8,10,602},{11,10,247},{11,10,826},{145,10,65},{138,11,558} +,{11,0,551},{142,0,159},{8,10,164},{146,10,62},{139,11,176},{132,0,168},{136,0, +1010},{134,0,1994},{135,0,91},{138,0,532},{135,10,1243},{135,0,1884},{132,10,907 +},{5,10,100},{10,10,329},{12,10,416},{149,10,29},{134,11,447},{132,10,176},{5,10 +,636},{5,10,998},{7,10,9},{7,10,1508},{8,10,26},{9,10,317},{9,10,358},{10,10,210 +},{10,10,292},{10,10,533},{11,10,555},{12,10,526},{12,10,607},{13,10,263},{13,10 +,459},{142,10,271},{4,11,609},{135,11,756},{6,0,15},{7,0,70},{10,0,240},{147,0, +93},{4,11,930},{133,11,947},{134,0,1227},{134,0,1534},{133,11,939},{133,11,962}, +{5,11,651},{8,11,170},{9,11,61},{9,11,63},{10,11,23},{10,11,37},{10,11,834},{11, +11,4},{11,11,187},{11,11,281},{11,11,503},{11,11,677},{12,11,96},{12,11,130},{12 +,11,244},{14,11,5},{14,11,40},{14,11,162},{14,11,202},{146,11,133},{4,11,406},{5 +,11,579},{12,11,492},{150,11,15},{139,0,392},{6,10,610},{10,10,127},{141,10,27}, +{7,0,655},{7,0,1844},{136,10,119},{4,0,145},{6,0,176},{7,0,395},{137,0,562},{132 +,0,501},{140,11,145},{136,0,1019},{134,0,509},{139,0,267},{6,11,17},{7,11,16},{7 +,11,1001},{7,11,1982},{9,11,886},{10,11,489},{10,11,800},{11,11,782},{12,11,320} +,{13,11,467},{14,11,145},{14,11,387},{143,11,119},{145,11,17},{5,11,458},{134,0, +1099},{7,11,1983},{8,11,0},{8,11,171},{9,11,120},{9,11,732},{10,11,473},{11,11, +656},{11,11,998},{18,11,0},{18,11,2},{147,11,21},{12,11,427},{146,11,38},{10,0, +948},{138,0,968},{7,10,126},{136,10,84},{136,10,790},{4,0,114},{9,0,492},{13,0, +462},{142,0,215},{6,10,64},{12,10,377},{141,10,309},{4,0,77},{5,0,361},{6,0,139} +,{6,0,401},{6,0,404},{7,0,413},{7,0,715},{7,0,1716},{11,0,279},{12,0,179},{12,0, +258},{13,0,244},{142,0,358},{134,0,1717},{7,0,772},{7,0,1061},{7,0,1647},{7,10, +1104},{8,0,82},{11,0,250},{11,0,607},{11,10,269},{11,10,539},{11,10,627},{11,10, +706},{11,10,975},{12,0,311},{12,0,420},{12,10,248},{12,10,434},{12,10,600},{12, +10,622},{13,0,184},{13,0,367},{13,10,297},{13,10,485},{14,10,69},{14,10,409},{ +143,10,108},{135,0,724},{4,11,512},{4,11,519},{133,11,342},{134,0,1133},{145,11, +29},{11,10,977},{141,10,507},{6,0,841},{6,0,1042},{6,0,1194},{10,0,993},{140,0, +1021},{6,11,31},{7,11,491},{7,11,530},{8,11,592},{9,10,34},{11,10,484},{11,11,53 +},{11,11,779},{12,11,167},{12,11,411},{14,11,14},{14,11,136},{15,11,72},{16,11, +17},{144,11,72},{4,0,1021},{5,11,907},{134,0,2037},{6,10,1700},{7,0,373},{7,10, +293},{7,10,382},{7,10,1026},{7,10,1087},{7,10,2027},{8,0,335},{8,0,596},{8,10, +252},{8,10,727},{8,10,729},{9,0,488},{9,10,30},{9,10,199},{9,10,231},{9,10,251}, +{9,10,334},{9,10,361},{9,10,712},{10,10,55},{10,10,60},{10,10,232},{10,10,332},{ +10,10,384},{10,10,396},{10,10,504},{10,10,542},{10,10,652},{11,10,20},{11,10,48} +,{11,10,207},{11,10,291},{11,10,298},{11,10,342},{11,10,365},{11,10,394},{11,10, +620},{11,10,705},{11,10,1017},{12,10,123},{12,10,340},{12,10,406},{12,10,643},{ +13,10,61},{13,10,269},{13,10,311},{13,10,319},{13,10,486},{14,10,234},{15,10,62} +,{15,10,85},{16,10,71},{18,10,119},{148,10,105},{150,0,37},{4,11,208},{5,11,106} +,{6,11,531},{8,11,408},{9,11,188},{138,11,572},{132,0,564},{6,0,513},{135,0,1052 +},{132,0,825},{9,0,899},{140,11,441},{134,0,778},{133,11,379},{7,0,1417},{12,0, +382},{17,0,48},{152,0,12},{132,11,241},{6,10,379},{7,0,1116},{7,10,270},{8,10, +176},{8,10,183},{9,10,432},{9,10,661},{12,10,247},{12,10,617},{146,10,125},{5,10 +,792},{133,10,900},{6,0,545},{7,0,565},{7,0,1669},{10,0,114},{11,0,642},{140,0, +618},{133,0,5},{138,11,7},{132,11,259},{135,0,192},{134,0,701},{136,0,763},{135, +10,1979},{4,10,901},{133,10,776},{10,0,755},{147,0,29},{133,0,759},{4,11,173},{5 +,11,312},{5,11,512},{135,11,1285},{7,11,1603},{7,11,1691},{9,11,464},{11,11,195} +,{12,11,279},{12,11,448},{14,11,11},{147,11,102},{7,0,370},{7,0,1007},{7,0,1177} +,{135,0,1565},{135,0,1237},{4,0,87},{5,0,250},{141,0,298},{4,11,452},{5,11,583}, +{5,11,817},{6,11,433},{7,11,593},{7,11,720},{7,11,1378},{8,11,161},{9,11,284},{ +10,11,313},{139,11,886},{4,11,547},{135,11,1409},{136,11,722},{4,10,37},{5,10, +334},{135,10,1253},{132,10,508},{12,0,107},{146,0,31},{8,11,420},{139,11,193},{ +135,0,814},{135,11,409},{140,0,991},{4,0,57},{7,0,1195},{7,0,1438},{7,0,1548},{7 +,0,1835},{7,0,1904},{9,0,757},{10,0,604},{139,0,519},{132,0,540},{138,11,308},{ +132,10,533},{136,0,608},{144,11,65},{4,0,1014},{134,0,2029},{4,0,209},{5,11,1002 +},{7,0,902},{136,11,745},{134,0,2030},{6,0,303},{7,0,335},{7,0,1437},{7,0,1668}, +{8,0,553},{8,0,652},{8,0,656},{9,0,558},{11,0,743},{149,0,18},{5,11,575},{6,11, +354},{135,11,701},{4,11,239},{6,11,477},{7,11,1607},{11,11,68},{139,11,617},{132 +,0,559},{8,0,527},{18,0,60},{147,0,24},{133,10,920},{138,0,511},{133,0,1017},{ +133,0,675},{138,10,391},{7,10,1952},{139,0,156},{138,11,369},{132,11,367},{133,0 +,709},{6,0,698},{134,0,887},{142,10,126},{134,0,1745},{132,10,483},{13,11,299},{ +142,11,75},{133,0,714},{7,0,8},{136,0,206},{138,10,480},{4,11,694},{9,10,495},{ +146,10,104},{7,11,1248},{11,11,621},{139,11,702},{140,11,687},{132,0,776},{139, +10,1009},{135,0,1272},{134,0,1059},{8,10,653},{13,10,93},{147,10,14},{135,11,213 +},{136,0,406},{133,10,172},{132,0,947},{8,0,175},{10,0,168},{138,0,573},{132,0, +870},{6,0,1567},{151,11,28},{134,11,472},{5,10,260},{136,11,132},{4,11,751},{11, +11,390},{140,11,32},{4,11,409},{133,11,78},{6,11,473},{12,0,554},{145,11,105},{ +133,0,784},{8,0,908},{136,11,306},{139,0,882},{6,0,358},{7,0,1393},{7,11,1759},{ +8,0,396},{8,11,396},{10,0,263},{10,11,263},{14,0,154},{14,11,154},{16,0,48},{16, +11,48},{17,0,8},{145,11,8},{13,11,163},{13,11,180},{18,11,78},{148,11,35},{14,0, +32},{18,0,85},{20,0,2},{152,0,16},{7,0,228},{8,10,167},{8,10,375},{9,10,82},{9, +10,561},{10,0,770},{138,10,620},{132,0,845},{9,0,14},{9,0,441},{10,0,306},{139,0 +,9},{8,10,194},{8,10,756},{11,0,966},{12,0,287},{13,0,342},{13,0,402},{15,0,110} +,{143,0,163},{134,0,1578},{4,0,967},{6,0,1820},{6,0,1847},{140,0,716},{136,0,594 +},{7,0,1428},{7,0,1640},{7,0,1867},{7,11,883},{9,0,169},{9,0,182},{9,0,367},{9,0 +,478},{9,0,506},{9,0,551},{9,0,557},{9,0,648},{9,0,697},{9,0,705},{9,0,725},{9,0 +,787},{9,0,794},{10,0,198},{10,0,214},{10,0,267},{10,0,275},{10,0,456},{10,0,551 +},{10,0,561},{10,0,613},{10,0,627},{10,0,668},{10,0,675},{10,0,691},{10,0,695},{ +10,0,707},{10,0,715},{11,0,183},{11,0,201},{11,0,244},{11,0,262},{11,0,352},{11, +0,439},{11,0,493},{11,0,572},{11,0,591},{11,0,608},{11,0,611},{11,0,646},{11,0, +674},{11,0,711},{11,0,751},{11,0,761},{11,0,776},{11,0,785},{11,0,850},{11,0,853 +},{11,0,862},{11,0,865},{11,0,868},{11,0,875},{11,0,898},{11,0,902},{11,0,903},{ +11,0,910},{11,0,932},{11,0,942},{11,0,957},{11,0,967},{11,0,972},{12,0,148},{12, +0,195},{12,0,220},{12,0,237},{12,0,318},{12,0,339},{12,0,393},{12,0,445},{12,0, +450},{12,0,474},{12,0,505},{12,0,509},{12,0,533},{12,0,591},{12,0,594},{12,0,597 +},{12,0,621},{12,0,633},{12,0,642},{13,0,59},{13,0,60},{13,0,145},{13,0,239},{13 +,0,250},{13,0,329},{13,0,344},{13,0,365},{13,0,372},{13,0,387},{13,0,403},{13,0, +414},{13,0,456},{13,0,470},{13,0,478},{13,0,483},{13,0,489},{14,0,55},{14,0,57}, +{14,0,81},{14,0,90},{14,0,148},{14,0,239},{14,0,266},{14,0,321},{14,0,326},{14,0 +,327},{14,0,330},{14,0,347},{14,0,355},{14,0,401},{14,0,404},{14,0,411},{14,0, +414},{14,0,416},{14,0,420},{15,0,61},{15,0,74},{15,0,87},{15,0,88},{15,0,94},{15 +,0,96},{15,0,116},{15,0,149},{15,0,154},{16,0,50},{16,0,63},{16,0,73},{17,0,2},{ +17,0,66},{17,0,92},{17,0,103},{17,0,112},{17,0,120},{18,0,50},{18,0,54},{18,0,82 +},{18,0,86},{18,0,90},{18,0,111},{18,0,115},{18,0,156},{19,0,40},{19,0,79},{20,0 +,78},{149,0,22},{5,0,161},{135,0,839},{4,0,782},{13,11,293},{142,11,56},{133,11, +617},{139,11,50},{135,10,22},{145,0,64},{5,10,639},{7,10,1249},{139,10,896},{138 +,0,998},{135,11,2042},{4,11,546},{142,11,233},{6,0,1043},{134,0,1574},{134,0, +1496},{4,10,102},{7,10,815},{7,10,1699},{139,10,964},{12,0,781},{142,0,461},{4, +11,313},{133,11,577},{6,0,639},{6,0,1114},{137,0,817},{8,11,184},{141,11,433},{7 +,0,1814},{135,11,935},{10,0,997},{140,0,958},{4,0,812},{137,11,625},{132,10,899} +,{136,10,795},{5,11,886},{6,11,46},{6,11,1790},{7,11,14},{7,11,732},{7,11,1654}, +{8,11,95},{8,11,327},{8,11,616},{10,11,598},{10,11,769},{11,11,134},{11,11,747}, +{12,11,378},{142,11,97},{136,0,139},{6,10,52},{9,10,104},{9,10,559},{12,10,308}, +{147,10,87},{133,11,1021},{132,10,604},{132,10,301},{136,10,779},{7,0,643},{136, +0,236},{132,11,153},{134,0,1172},{147,10,32},{133,11,798},{4,11,587},{134,0,1338 +},{6,11,598},{7,11,42},{8,11,695},{10,11,212},{11,11,158},{14,11,196},{145,11,85 +},{135,10,508},{5,11,957},{5,11,1008},{135,11,249},{4,11,129},{135,11,465},{5,0, +54},{7,11,470},{7,11,1057},{7,11,1201},{9,11,755},{11,11,906},{140,11,527},{7,11 +,908},{146,11,7},{5,11,148},{136,11,450},{144,11,1},{4,0,256},{135,0,1488},{6,10 +,310},{7,10,1849},{8,10,72},{8,10,272},{8,10,431},{9,0,351},{9,10,12},{10,10,563 +},{10,10,630},{10,10,796},{10,10,810},{11,10,367},{11,10,599},{11,10,686},{140, +10,672},{6,0,1885},{6,0,1898},{6,0,1899},{140,0,955},{4,0,714},{133,0,469},{6,0, +1270},{134,0,1456},{132,0,744},{6,0,313},{7,10,537},{8,10,64},{9,10,127},{10,10, +496},{12,10,510},{141,10,384},{4,10,244},{4,11,217},{5,11,710},{7,10,233},{7,11, +1926},{9,11,428},{9,11,708},{10,11,254},{10,11,296},{10,11,720},{11,11,109},{11, +11,255},{12,11,165},{12,11,315},{13,11,107},{13,11,203},{14,11,54},{14,11,99},{ +14,11,114},{14,11,388},{16,11,85},{17,11,9},{17,11,33},{20,11,25},{20,11,28},{20 +,11,29},{21,11,9},{21,11,10},{21,11,34},{150,11,17},{138,0,402},{7,0,969},{146,0 +,55},{8,0,50},{137,0,624},{134,0,1355},{132,0,572},{134,10,1650},{10,10,702},{ +139,10,245},{10,0,847},{142,0,445},{6,0,43},{7,0,38},{8,0,248},{138,0,513},{133, +0,369},{137,10,338},{133,0,766},{133,0,363},{133,10,896},{8,11,392},{11,11,54},{ +13,11,173},{13,11,294},{148,11,7},{134,0,678},{7,11,1230},{136,11,531},{6,0,258} +,{140,0,409},{5,0,249},{148,0,82},{7,10,1117},{136,10,539},{5,0,393},{6,0,378},{ +7,0,1981},{9,0,32},{9,0,591},{10,0,685},{10,0,741},{142,0,382},{133,0,788},{134, +0,1281},{134,0,1295},{7,0,1968},{141,0,509},{4,0,61},{5,0,58},{5,0,171},{5,0,683 +},{6,0,291},{6,0,566},{7,0,1650},{11,0,523},{12,0,273},{12,0,303},{15,0,39},{143 +,0,111},{6,0,706},{134,0,1283},{134,0,589},{135,11,1433},{133,11,435},{5,10,4},{ +5,10,810},{6,10,13},{6,10,538},{6,10,1690},{6,10,1726},{7,0,1059},{7,10,1819},{8 +,10,148},{8,10,696},{8,10,791},{12,10,125},{13,0,54},{143,10,9},{135,10,1268},{5 +,11,85},{6,11,419},{7,11,134},{7,11,305},{7,11,361},{7,11,1337},{8,11,71},{140, +11,519},{137,0,824},{140,11,688},{5,11,691},{7,10,1385},{7,11,345},{9,11,94},{11 +,10,582},{11,10,650},{11,10,901},{11,10,949},{12,10,232},{12,10,236},{12,11,169} +,{13,10,413},{13,10,501},{146,10,116},{4,0,917},{133,0,1005},{5,11,183},{6,11, +582},{7,0,1598},{9,11,344},{10,11,679},{140,11,435},{4,10,925},{5,10,803},{8,10, +698},{138,10,828},{132,0,919},{135,11,511},{139,10,992},{4,0,255},{5,0,302},{6,0 +,132},{7,0,128},{7,0,283},{7,0,1299},{10,0,52},{10,0,514},{11,0,925},{13,0,92},{ +142,0,309},{134,0,1369},{135,10,1847},{134,0,328},{7,11,1993},{136,11,684},{133, +10,383},{137,0,173},{134,11,583},{134,0,1411},{5,11,704},{8,11,357},{10,11,745}, +{14,11,426},{17,11,94},{19,0,65},{147,11,57},{9,10,660},{138,10,347},{4,11,179}, +{5,11,198},{133,11,697},{7,11,347},{7,11,971},{8,11,181},{138,11,711},{141,0,442 +},{7,10,572},{9,10,592},{11,0,842},{11,0,924},{11,10,680},{12,10,356},{12,10,550 +},{13,0,317},{13,0,370},{13,0,469},{13,0,471},{14,0,397},{18,0,69},{146,0,145},{ +14,11,19},{14,11,28},{144,11,29},{136,0,534},{4,11,243},{5,11,203},{7,11,19},{7, +11,71},{7,11,113},{10,11,405},{11,11,357},{142,11,240},{6,0,210},{10,0,845},{138 +,0,862},{7,11,1351},{9,11,581},{10,11,639},{11,11,453},{140,11,584},{7,11,1450}, +{139,11,99},{10,0,892},{12,0,719},{144,0,105},{4,0,284},{6,0,223},{134,11,492},{ +5,11,134},{6,11,408},{6,11,495},{135,11,1593},{136,0,529},{137,0,807},{4,0,218}, +{7,0,526},{143,0,137},{6,0,1444},{142,11,4},{132,11,665},{4,0,270},{4,11,248},{5 +,0,192},{6,0,332},{7,0,1322},{7,11,137},{137,11,349},{140,0,661},{7,0,1517},{7, +10,748},{11,0,597},{11,10,700},{14,0,76},{14,0,335},{148,0,33},{5,11,371},{135, +11,563},{146,11,57},{133,10,127},{133,0,418},{4,11,374},{7,11,547},{7,11,1700},{ +7,11,1833},{139,11,858},{6,10,198},{140,10,83},{7,11,1812},{13,11,259},{13,11, +356},{14,11,242},{147,11,114},{5,10,276},{6,10,55},{7,0,379},{7,10,1369},{8,0, +481},{137,0,377},{138,11,286},{5,0,1003},{6,0,149},{6,10,1752},{136,10,726},{6, +11,1647},{7,11,1552},{7,11,2010},{8,0,262},{9,0,627},{9,11,494},{9,11,509},{10,0 +,18},{11,0,214},{11,0,404},{11,0,457},{11,0,780},{11,0,913},{13,0,401},{142,0, +200},{135,0,742},{136,0,304},{132,0,142},{133,10,764},{6,10,309},{7,10,331},{138 +,10,550},{135,10,1062},{6,11,123},{7,10,986},{7,11,214},{9,11,728},{10,11,157},{ +11,11,346},{11,11,662},{143,11,106},{135,10,1573},{7,0,925},{137,0,799},{4,0,471 +},{5,0,51},{6,0,602},{8,0,484},{138,0,195},{136,0,688},{132,0,697},{6,0,1169},{6 +,0,1241},{6,10,194},{7,10,133},{10,10,493},{10,10,570},{139,10,664},{140,0,751}, +{5,10,24},{5,10,569},{6,10,3},{6,10,119},{6,10,143},{6,10,440},{7,0,929},{7,10, +599},{7,10,1686},{7,10,1854},{8,10,424},{9,10,43},{9,10,584},{9,10,760},{10,0, +452},{10,10,328},{11,0,878},{11,10,159},{11,10,253},{12,10,487},{12,10,531},{144 +,0,33},{4,11,707},{13,11,106},{18,11,49},{147,11,41},{5,0,221},{5,11,588},{134, +11,393},{134,0,1437},{6,11,211},{7,11,1690},{11,11,486},{140,11,369},{5,10,14},{ +5,10,892},{6,10,283},{7,10,234},{136,10,537},{4,0,988},{136,0,955},{135,0,1251}, +{4,10,126},{8,10,635},{147,10,34},{4,10,316},{135,10,1561},{137,10,861},{4,10,64 +},{5,10,352},{5,10,720},{6,10,368},{139,10,359},{134,0,192},{4,0,132},{5,0,69},{ +135,0,1242},{7,10,1577},{10,10,304},{10,10,549},{12,10,365},{13,10,220},{13,10, +240},{142,10,33},{4,0,111},{6,11,219},{135,0,865},{5,11,582},{6,11,1646},{7,11, +99},{7,11,1962},{7,11,1986},{8,11,515},{8,11,773},{9,11,23},{9,11,491},{12,11, +620},{14,11,52},{145,11,50},{132,0,767},{7,11,568},{148,11,21},{5,11,851},{6,0, +42},{7,0,1416},{7,0,2005},{8,0,131},{8,0,466},{9,0,672},{13,0,252},{148,0,103},{ +135,0,1050},{6,10,175},{137,10,289},{5,10,432},{133,10,913},{6,0,44},{136,0,368} +,{135,11,784},{132,0,570},{133,0,120},{139,10,595},{140,0,29},{6,0,227},{135,0, +1589},{4,11,98},{7,11,1365},{9,11,422},{9,11,670},{10,11,775},{11,11,210},{13,11 +,26},{13,11,457},{141,11,476},{140,10,80},{5,10,931},{134,10,1698},{133,0,522},{ +134,0,1120},{135,0,1529},{12,0,739},{14,0,448},{142,0,467},{11,10,526},{11,10, +939},{141,10,290},{5,10,774},{6,10,1637},{6,10,1686},{134,10,1751},{6,0,1667},{ +135,0,2036},{7,10,1167},{11,10,934},{13,10,391},{145,10,76},{137,11,147},{6,10, +260},{7,10,1484},{11,11,821},{12,11,110},{12,11,153},{18,11,41},{150,11,19},{6,0 +,511},{6,10,573},{140,0,132},{5,0,568},{6,0,138},{135,0,1293},{132,0,1020},{8,0, +258},{9,0,208},{137,0,359},{4,0,565},{8,0,23},{136,0,827},{134,0,344},{4,0,922}, +{5,0,1023},{13,11,477},{14,11,120},{148,11,61},{134,0,240},{5,11,209},{6,11,30}, +{11,11,56},{139,11,305},{4,10,292},{4,10,736},{5,10,871},{6,0,171},{6,10,1689},{ +7,0,1002},{7,0,1324},{7,10,1944},{9,0,415},{9,10,580},{14,0,230},{146,0,68},{9, +11,635},{139,11,559},{4,11,150},{5,11,303},{134,11,327},{6,10,63},{135,10,920},{ +133,10,793},{8,11,192},{10,11,78},{10,11,555},{11,11,308},{13,11,359},{147,11,95 +},{135,11,786},{135,11,1712},{136,0,402},{6,0,754},{6,11,1638},{7,11,79},{7,11, +496},{9,11,138},{10,11,336},{11,11,12},{12,11,412},{12,11,440},{142,11,305},{4,0 +,716},{141,0,31},{133,0,982},{5,10,67},{6,10,62},{6,10,374},{7,10,1391},{8,0,691 +},{136,0,731},{9,10,790},{140,10,47},{139,11,556},{151,11,1},{7,11,204},{7,11, +415},{8,11,42},{10,11,85},{11,11,33},{11,11,564},{12,11,571},{149,11,1},{7,11, +610},{7,11,1501},{136,0,888},{4,10,391},{135,10,1169},{5,0,847},{9,0,840},{138,0 +,803},{137,0,823},{134,0,785},{8,0,152},{9,0,53},{9,0,268},{9,0,901},{10,0,518}, +{10,0,829},{11,0,188},{13,0,74},{14,0,46},{15,0,17},{15,0,33},{17,0,40},{18,0,36 +},{19,0,20},{22,0,1},{152,0,2},{4,11,3},{5,11,247},{5,11,644},{7,11,744},{7,11, +1207},{7,11,1225},{7,11,1909},{146,11,147},{136,0,532},{135,0,681},{132,10,271}, +{140,0,314},{140,0,677},{4,0,684},{136,0,384},{5,11,285},{9,11,67},{13,11,473},{ +143,11,82},{4,10,253},{5,10,544},{7,10,300},{137,10,340},{7,0,110},{7,0,447},{8, +0,290},{8,0,591},{9,0,382},{9,0,649},{11,0,71},{11,0,155},{11,0,313},{12,0,5},{ +13,0,325},{142,0,287},{134,0,1818},{136,0,1007},{138,0,321},{7,0,360},{7,0,425}, +{9,0,66},{9,0,278},{138,0,644},{133,10,818},{5,0,385},{5,10,541},{6,10,94},{6,10 +,499},{7,10,230},{139,10,321},{4,10,920},{5,10,25},{5,10,790},{6,10,457},{7,10, +853},{136,10,788},{4,0,900},{133,0,861},{5,0,254},{7,0,985},{136,0,73},{7,0,1959 +},{136,0,683},{134,10,1765},{133,10,822},{132,10,634},{4,11,29},{6,11,532},{7,11 +,1628},{7,11,1648},{9,11,303},{9,11,350},{10,11,433},{11,11,97},{11,11,557},{11, +11,745},{12,11,289},{12,11,335},{12,11,348},{12,11,606},{13,11,116},{13,11,233}, +{13,11,466},{14,11,181},{14,11,209},{14,11,232},{14,11,236},{14,11,300},{16,11, +41},{148,11,97},{6,10,36},{7,10,658},{8,10,454},{147,0,86},{135,11,1692},{132,0, +725},{5,11,501},{7,11,1704},{9,11,553},{11,11,520},{12,11,557},{141,11,249},{134 +,0,196},{133,0,831},{136,0,723},{7,0,1897},{13,0,80},{13,0,437},{145,0,74},{4,0, +992},{6,0,627},{136,0,994},{135,11,1294},{132,10,104},{5,0,848},{6,0,66},{136,0, +764},{4,0,36},{7,0,1387},{10,0,205},{139,0,755},{6,0,1046},{134,0,1485},{134,0, +950},{132,0,887},{14,0,450},{148,0,111},{7,0,620},{7,0,831},{9,10,542},{9,10,566 +},{138,10,728},{6,0,165},{138,0,388},{139,10,263},{4,0,719},{135,0,155},{138,10, +468},{6,11,453},{144,11,36},{134,11,129},{5,0,533},{7,0,755},{138,0,780},{134,0, +1465},{4,0,353},{6,0,146},{6,0,1789},{7,0,427},{7,0,990},{7,0,1348},{9,0,665},{9 +,0,898},{11,0,893},{142,0,212},{7,10,87},{142,10,288},{4,0,45},{135,0,1257},{7, +10,988},{7,10,1939},{9,10,64},{9,10,502},{12,0,7},{12,10,34},{13,10,12},{13,10, +234},{147,10,77},{4,0,607},{5,11,60},{6,11,504},{7,11,614},{7,11,1155},{140,11,0 +},{135,10,141},{8,11,198},{11,11,29},{140,11,534},{140,0,65},{136,0,816},{132,10 +,619},{139,0,88},{5,10,246},{8,10,189},{9,10,355},{9,10,512},{10,10,124},{10,10, +453},{11,10,143},{11,10,416},{11,10,859},{141,10,341},{4,11,379},{135,11,1397},{ +4,0,600},{137,0,621},{133,0,367},{134,0,561},{6,0,559},{134,0,1691},{6,0,585},{ +134,11,585},{135,11,1228},{4,11,118},{5,10,678},{6,11,274},{6,11,361},{7,11,75}, +{141,11,441},{135,11,1818},{137,11,841},{5,0,573},{6,0,287},{7,10,862},{7,10, +1886},{138,10,179},{132,10,517},{140,11,693},{5,11,314},{6,11,221},{7,11,419},{ +10,11,650},{11,11,396},{12,11,156},{13,11,369},{14,11,333},{145,11,47},{140,10, +540},{136,10,667},{11,10,403},{146,10,83},{5,10,761},{134,0,672},{9,0,157},{10, +10,131},{140,10,72},{6,11,460},{135,0,714},{134,0,456},{133,0,925},{5,11,682},{ +135,11,1887},{136,11,510},{136,11,475},{133,11,1016},{7,11,602},{8,11,179},{9,0, +19},{10,11,781},{140,11,126},{6,11,329},{138,11,111},{6,0,822},{134,0,1473},{144 +,11,86},{11,0,113},{139,11,113},{5,11,821},{134,11,1687},{133,10,449},{7,0,463}, +{8,10,103},{145,0,69},{7,10,2028},{138,10,641},{6,0,193},{7,0,240},{7,0,1682},{ +10,0,51},{10,0,640},{11,0,410},{13,0,82},{14,0,247},{14,0,331},{142,0,377},{6,0, +471},{11,0,411},{142,0,2},{5,11,71},{7,11,1407},{9,11,388},{9,11,704},{10,11,261 +},{10,11,619},{11,11,547},{11,11,619},{143,11,157},{136,0,633},{135,0,1148},{6,0 +,554},{7,0,1392},{7,10,1274},{7,10,1386},{7,11,2008},{9,11,337},{10,11,517},{12, +0,129},{146,10,87},{6,10,187},{7,0,803},{7,10,1203},{8,0,542},{8,10,380},{14,10, +117},{149,10,28},{6,10,297},{7,10,793},{139,10,938},{7,10,464},{8,0,438},{11,0, +363},{11,10,105},{12,10,231},{14,10,386},{15,10,102},{148,10,75},{5,11,16},{6,11 +,86},{6,11,603},{7,11,292},{7,11,561},{8,11,257},{8,11,382},{9,11,721},{9,11,778 +},{11,11,581},{140,11,466},{4,11,486},{5,11,491},{134,0,717},{132,0,875},{132,11 +,72},{6,11,265},{135,11,847},{4,0,237},{135,0,514},{6,0,392},{7,0,65},{135,0, +2019},{140,11,261},{135,11,922},{137,11,404},{7,10,1010},{11,10,733},{11,10,759} +,{12,0,563},{13,10,34},{14,0,101},{18,0,129},{146,10,45},{7,10,1656},{9,10,369}, +{10,10,338},{10,10,490},{11,10,154},{11,10,545},{11,10,775},{13,10,77},{141,10, +274},{4,0,444},{10,0,146},{140,0,9},{139,11,163},{7,0,1260},{135,0,1790},{9,0, +222},{10,0,43},{139,0,900},{137,11,234},{138,0,971},{137,0,761},{134,0,699},{136 +,11,434},{5,10,20},{6,0,1116},{6,10,298},{6,11,197},{7,0,1366},{7,10,659},{8,11, +205},{137,10,219},{132,11,490},{11,11,820},{150,11,51},{7,10,1440},{11,10,854},{ +11,10,872},{11,10,921},{12,10,551},{13,10,472},{142,10,367},{140,11,13},{132,0, +829},{4,10,439},{140,0,242},{136,10,669},{6,0,593},{6,11,452},{7,11,312},{138,11 +,219},{4,11,333},{9,11,176},{12,11,353},{141,11,187},{7,0,36},{8,0,201},{136,0, +605},{140,0,224},{132,10,233},{134,0,1430},{134,0,1806},{4,0,523},{133,0,638},{6 +,0,1889},{9,0,958},{9,0,971},{9,0,976},{12,0,796},{12,0,799},{12,0,808},{12,0, +835},{12,0,836},{12,0,914},{12,0,946},{15,0,216},{15,0,232},{18,0,183},{18,0,187 +},{18,0,194},{18,0,212},{18,0,232},{149,0,49},{132,10,482},{6,0,827},{134,0,1434 +},{135,10,346},{134,0,2043},{6,0,242},{7,0,227},{7,0,1581},{8,0,104},{9,0,113},{ +9,0,220},{9,0,427},{10,0,136},{10,0,239},{11,0,579},{11,0,1023},{13,0,4},{13,0, +204},{13,0,316},{148,0,86},{134,11,1685},{7,0,148},{8,0,284},{141,0,63},{142,0, +10},{135,11,584},{134,0,1249},{7,0,861},{135,10,334},{5,10,795},{6,10,1741},{137 +,11,70},{132,0,807},{7,11,135},{8,11,7},{8,11,62},{9,11,243},{10,11,658},{10,11, +697},{11,11,456},{139,11,756},{9,11,395},{138,11,79},{137,11,108},{147,0,94},{ +136,0,494},{135,11,631},{135,10,622},{7,0,1510},{135,10,1750},{4,10,203},{135,10 +,1936},{7,11,406},{7,11,459},{8,11,606},{139,11,726},{7,0,1306},{8,0,505},{9,0, +482},{10,0,126},{11,0,225},{12,0,347},{12,0,449},{13,0,19},{14,0,218},{142,0,435 +},{5,0,268},{10,0,764},{12,0,120},{13,0,39},{145,0,127},{142,11,68},{11,10,678}, +{140,10,307},{12,11,268},{12,11,640},{142,11,119},{135,10,2044},{133,11,612},{4, +11,372},{7,11,482},{8,11,158},{9,11,602},{9,11,615},{10,11,245},{10,11,678},{10, +11,744},{11,11,248},{139,11,806},{7,10,311},{9,10,308},{140,10,255},{4,0,384},{ +135,0,1022},{5,11,854},{135,11,1991},{135,10,1266},{4,10,400},{5,10,267},{135,10 +,232},{135,0,1703},{9,0,159},{11,0,661},{140,0,603},{4,0,964},{9,11,106},{9,11, +163},{9,11,296},{10,11,167},{10,11,172},{10,11,777},{11,11,16},{14,0,438},{14,0, +444},{14,0,456},{22,0,60},{150,0,63},{136,0,583},{132,0,515},{8,0,632},{8,0,697} +,{137,0,854},{5,11,195},{135,11,1685},{6,0,1123},{134,0,1365},{134,11,328},{7,11 +,1997},{8,11,730},{139,11,1006},{4,0,136},{133,0,551},{134,0,1782},{7,0,1287},{9 +,0,44},{10,0,552},{10,0,642},{11,0,839},{12,0,274},{12,0,275},{12,0,372},{13,0, +91},{142,0,125},{5,11,751},{11,11,797},{140,11,203},{133,0,732},{4,10,100},{7,0, +679},{7,11,821},{136,0,313},{10,0,361},{142,0,316},{134,0,595},{6,0,147},{7,0, +886},{9,0,753},{138,0,268},{5,10,362},{5,10,443},{6,10,318},{7,10,1019},{139,10, +623},{5,10,463},{136,10,296},{4,10,454},{5,11,950},{5,11,994},{134,11,351},{138, +0,137},{5,10,48},{5,10,404},{6,10,557},{7,10,458},{8,10,597},{10,10,455},{10,10, +606},{11,10,49},{11,10,548},{12,10,476},{13,10,18},{141,10,450},{133,0,414},{135 +,0,1762},{5,11,421},{135,11,47},{5,10,442},{135,10,1984},{134,0,599},{134,0,1749 +},{134,0,1627},{4,0,488},{132,11,350},{137,11,751},{132,0,83},{140,0,676},{133, +11,967},{5,10,55},{7,0,1639},{140,10,161},{4,11,473},{7,11,623},{8,11,808},{9,11 +,871},{9,11,893},{11,11,38},{11,11,431},{12,11,112},{12,11,217},{12,11,243},{12, +11,562},{12,11,683},{13,11,141},{13,11,197},{13,11,227},{13,11,406},{13,11,487}, +{14,11,156},{14,11,203},{14,11,224},{14,11,256},{18,11,58},{150,11,0},{133,10, +450},{7,11,736},{139,11,264},{134,0,278},{4,11,222},{7,11,286},{136,11,629},{135 +,10,869},{140,0,97},{144,0,14},{134,0,1085},{4,10,213},{7,10,223},{136,10,80},{7 +,0,388},{7,0,644},{139,0,781},{132,0,849},{7,0,229},{8,0,59},{9,0,190},{10,0,378 +},{140,0,191},{7,10,381},{7,10,806},{7,10,820},{8,10,354},{8,10,437},{8,10,787}, +{9,10,657},{10,10,58},{10,10,339},{10,10,749},{11,10,914},{12,10,162},{13,10,75} +,{14,10,106},{14,10,198},{14,10,320},{14,10,413},{146,10,43},{141,11,306},{136, +10,747},{134,0,1115},{8,11,146},{16,0,94},{144,0,108},{6,0,700},{6,0,817},{134,0 +,1002},{133,10,692},{4,11,465},{135,11,1663},{134,10,191},{6,0,1414},{135,11,913 +},{132,0,660},{7,0,1035},{138,0,737},{6,10,162},{7,10,1960},{136,10,831},{132,10 +,706},{7,0,690},{9,0,217},{9,0,587},{140,0,521},{138,10,426},{135,10,1235},{6,11 +,82},{7,11,138},{7,11,517},{9,11,673},{139,11,238},{138,0,272},{5,11,495},{7,11, +834},{9,11,733},{139,11,378},{134,0,1744},{132,0,1011},{7,11,828},{142,11,116},{ +4,0,733},{5,11,559},{9,0,194},{10,0,92},{11,0,198},{12,0,84},{141,0,128},{6,11, +21},{6,11,1737},{7,11,1444},{8,11,224},{10,0,57},{138,0,277},{4,10,204},{137,10, +902},{136,10,833},{7,10,366},{9,10,287},{11,0,348},{12,0,99},{12,10,199},{12,10, +556},{12,10,577},{18,0,1},{18,0,11},{147,0,4},{6,0,1981},{136,0,936},{21,0,33},{ +150,0,40},{5,11,519},{138,11,204},{5,10,356},{135,10,224},{134,0,775},{135,0,306 +},{7,10,630},{9,10,567},{11,10,150},{11,10,444},{141,10,119},{5,0,979},{134,10, +539},{133,0,611},{4,11,402},{135,11,1679},{5,0,178},{7,11,2},{8,11,323},{136,11, +479},{5,11,59},{135,11,672},{4,0,1010},{6,0,1969},{138,11,237},{133,11,412},{146 +,11,34},{7,11,1740},{146,11,48},{134,0,664},{139,10,814},{4,11,85},{135,11,549}, +{133,11,94},{133,11,457},{132,0,390},{134,0,1510},{4,10,235},{135,10,255},{4,10, +194},{5,10,584},{6,10,384},{6,11,11},{7,10,583},{7,11,187},{10,10,761},{11,10, +760},{139,10,851},{4,11,522},{139,11,802},{135,0,493},{10,11,776},{13,11,345},{ +142,11,425},{146,0,37},{4,11,52},{135,11,661},{134,0,724},{134,0,829},{133,11, +520},{133,10,562},{4,11,281},{5,11,38},{7,11,194},{7,11,668},{7,11,1893},{137,11 +,397},{5,10,191},{137,10,271},{7,0,1537},{14,0,96},{143,0,73},{4,10,470},{5,0, +473},{6,10,153},{7,10,1503},{7,10,1923},{10,10,701},{11,0,168},{11,10,132},{11, +10,227},{11,10,320},{11,10,436},{11,10,525},{11,10,855},{12,10,41},{12,10,286},{ +13,10,103},{13,10,284},{14,10,255},{14,10,262},{15,10,117},{143,10,127},{133,0, +105},{5,0,438},{9,0,694},{12,0,627},{141,0,210},{133,10,327},{6,10,552},{7,10, +1754},{137,10,604},{134,0,1256},{152,0,11},{5,11,448},{11,11,98},{139,11,524},{5 +,10,80},{6,10,405},{7,0,1626},{7,10,403},{7,10,1502},{8,10,456},{9,10,487},{9,10 +,853},{9,10,889},{10,10,309},{11,10,721},{11,10,994},{12,10,430},{13,10,165},{14 +,11,16},{146,11,44},{132,0,779},{8,0,25},{138,0,826},{4,10,453},{5,10,887},{6,10 +,535},{8,10,6},{8,10,543},{136,10,826},{137,11,461},{140,11,632},{132,0,308},{ +135,0,741},{132,0,671},{7,0,150},{8,0,649},{136,0,1020},{6,11,336},{8,11,552},{9 +,0,99},{9,11,285},{10,11,99},{139,11,568},{134,0,521},{5,0,339},{14,0,3},{15,0, +41},{15,0,166},{147,0,66},{6,11,423},{7,11,665},{7,11,1210},{9,11,218},{141,11, +222},{5,10,101},{5,11,256},{6,0,543},{6,10,88},{7,10,1677},{9,10,100},{10,10,677 +},{14,10,169},{14,10,302},{14,10,313},{15,10,48},{143,10,84},{4,10,310},{7,10, +708},{7,10,996},{9,10,795},{10,10,390},{10,10,733},{11,10,451},{12,10,249},{14, +10,115},{14,10,286},{143,10,100},{133,10,587},{13,11,417},{14,11,129},{143,11,15 +},{134,0,1358},{136,11,554},{132,10,498},{7,10,217},{8,10,140},{138,10,610},{135 +,11,989},{135,11,634},{6,0,155},{140,0,234},{135,11,462},{132,11,618},{134,0, +1628},{132,0,766},{4,11,339},{5,10,905},{135,11,259},{135,0,829},{4,11,759},{141 +,11,169},{4,10,456},{7,0,1445},{7,10,358},{7,10,1637},{8,10,643},{139,10,483},{5 +,0,486},{135,0,1349},{5,11,688},{135,11,712},{7,0,1635},{8,0,17},{10,0,217},{10, +0,295},{12,0,2},{140,11,2},{138,0,558},{150,10,56},{4,11,278},{5,11,465},{135,11 +,1367},{136,11,482},{133,10,535},{6,0,1362},{6,0,1461},{10,11,274},{10,11,625},{ +139,11,530},{5,0,599},{5,11,336},{6,11,341},{6,11,478},{6,11,1763},{136,11,386}, +{7,10,1748},{137,11,151},{134,0,1376},{133,10,539},{135,11,73},{135,11,1971},{ +139,11,283},{9,0,93},{139,0,474},{6,10,91},{135,10,435},{5,11,396},{6,0,447},{ +134,11,501},{4,10,16},{5,10,316},{5,10,842},{6,10,370},{6,10,1778},{8,10,166},{ +11,10,812},{12,10,206},{12,10,351},{14,10,418},{16,10,15},{16,10,34},{18,10,3},{ +19,10,3},{19,10,7},{20,10,4},{149,10,21},{7,0,577},{7,0,1432},{9,0,475},{9,0,505 +},{9,0,526},{9,0,609},{9,0,689},{9,0,726},{9,0,735},{9,0,738},{10,0,556},{10,0, +674},{10,0,684},{11,0,89},{11,0,202},{11,0,272},{11,0,380},{11,0,415},{11,0,505} +,{11,0,537},{11,0,550},{11,0,562},{11,0,640},{11,0,667},{11,0,688},{11,0,847},{ +11,0,927},{11,0,930},{11,0,940},{12,0,144},{12,0,325},{12,0,329},{12,0,389},{12, +0,403},{12,0,451},{12,0,515},{12,0,604},{12,0,616},{12,0,626},{13,0,66},{13,0, +131},{13,0,167},{13,0,236},{13,0,368},{13,0,411},{13,0,434},{13,0,453},{13,0,461 +},{13,0,474},{14,0,59},{14,0,60},{14,0,139},{14,0,152},{14,0,276},{14,0,353},{14 +,0,402},{15,0,28},{15,0,81},{15,0,123},{15,0,152},{18,0,136},{148,0,88},{4,11, +929},{133,11,799},{136,11,46},{142,0,307},{4,0,609},{7,0,756},{9,0,544},{11,0, +413},{144,0,25},{7,10,619},{10,0,687},{10,10,547},{11,10,122},{140,10,601},{4,0, +930},{133,0,947},{133,0,939},{142,0,21},{4,11,892},{133,11,770},{133,0,962},{5,0 +,651},{8,0,170},{9,0,61},{9,0,63},{10,0,23},{10,0,37},{10,0,834},{11,0,4},{11,0, +187},{11,0,281},{11,0,503},{11,0,677},{12,0,96},{12,0,130},{12,0,244},{14,0,5},{ +14,0,40},{14,0,162},{14,0,202},{146,0,133},{4,0,406},{5,0,579},{12,0,492},{150,0 +,15},{135,11,158},{135,0,597},{132,0,981},{132,10,888},{4,10,149},{138,10,368},{ +132,0,545},{4,10,154},{7,10,1134},{136,10,105},{135,11,2001},{134,0,1558},{4,10, +31},{6,10,429},{7,10,962},{9,10,458},{139,10,691},{132,10,312},{135,10,1642},{6, +0,17},{6,0,1304},{7,0,16},{7,0,1001},{9,0,886},{10,0,489},{10,0,800},{11,0,782}, +{12,0,320},{13,0,467},{14,0,145},{14,0,387},{143,0,119},{135,0,1982},{7,11,1461} +,{12,11,91},{145,0,17},{4,10,236},{132,11,602},{138,0,907},{136,0,110},{5,10,836 +},{5,10,857},{6,10,1680},{7,0,272},{147,0,53},{5,0,458},{7,11,1218},{136,11,303} +,{7,0,1983},{8,0,0},{8,0,171},{9,0,120},{9,0,732},{10,0,473},{10,10,68},{11,0, +656},{11,0,998},{11,10,494},{18,0,0},{18,0,2},{147,0,21},{137,11,662},{4,11,13}, +{5,11,567},{7,11,1498},{9,11,124},{11,11,521},{140,11,405},{4,10,81},{139,10,867 +},{135,11,1006},{7,11,800},{7,11,1783},{138,11,12},{5,10,282},{8,10,650},{9,0, +295},{9,10,907},{138,0,443},{132,11,735},{4,10,775},{4,11,170},{135,11,323},{6,0 +,1844},{10,0,924},{11,11,844},{12,11,104},{140,11,625},{5,11,304},{7,11,1403},{ +140,11,498},{134,0,1232},{4,0,519},{10,0,70},{12,0,26},{14,0,17},{14,0,178},{15, +0,34},{149,0,12},{132,0,993},{4,11,148},{133,11,742},{6,0,31},{7,0,491},{7,0,530 +},{8,0,592},{11,0,53},{11,0,779},{12,0,167},{12,0,411},{14,0,14},{14,0,136},{15, +0,72},{16,0,17},{144,0,72},{133,0,907},{134,0,733},{133,11,111},{4,10,71},{5,10, +376},{7,10,119},{138,10,665},{136,0,55},{8,0,430},{136,11,430},{4,0,208},{5,0, +106},{6,0,531},{8,0,408},{9,0,188},{138,0,572},{11,10,827},{12,0,56},{14,10,34}, +{143,10,148},{134,0,1693},{133,11,444},{132,10,479},{140,0,441},{9,0,449},{10,0, +192},{138,0,740},{134,0,928},{4,0,241},{7,10,607},{136,10,99},{8,11,123},{15,11, +6},{144,11,7},{6,11,285},{8,11,654},{11,11,749},{12,11,190},{12,11,327},{13,11, +120},{13,11,121},{13,11,327},{15,11,47},{146,11,40},{4,10,41},{5,10,74},{7,10, +1627},{11,10,871},{140,10,619},{7,0,1525},{11,10,329},{11,10,965},{12,10,241},{ +14,10,354},{15,10,22},{148,10,63},{132,0,259},{135,11,183},{9,10,209},{137,10, +300},{5,11,937},{135,11,100},{133,10,98},{4,0,173},{5,0,312},{5,0,512},{135,0, +1285},{141,0,185},{7,0,1603},{7,0,1691},{9,0,464},{11,0,195},{12,0,279},{12,0, +448},{14,0,11},{147,0,102},{135,0,1113},{133,10,984},{4,0,452},{5,0,583},{135,0, +720},{4,0,547},{5,0,817},{6,0,433},{7,0,593},{7,0,1378},{8,0,161},{9,0,284},{10, +0,313},{139,0,886},{4,10,182},{6,10,205},{7,10,220},{136,0,722},{150,0,13},{4,10 +,42},{9,10,205},{9,10,786},{138,10,659},{6,0,289},{7,0,1670},{12,0,57},{151,0,4} +,{132,10,635},{14,0,43},{146,0,21},{139,10,533},{135,0,1694},{8,0,420},{139,0, +193},{135,0,409},{132,10,371},{4,10,272},{135,10,836},{5,10,825},{134,10,1640},{ +5,11,251},{5,11,956},{8,11,268},{9,11,214},{146,11,142},{138,0,308},{6,0,1863},{ +141,11,37},{137,10,879},{7,10,317},{135,10,569},{132,11,294},{134,0,790},{5,0, +1002},{136,0,745},{5,11,346},{5,11,711},{136,11,390},{135,0,289},{5,0,504},{9,10 +,307},{139,0,68},{4,0,239},{6,0,477},{7,0,1607},{139,0,617},{149,0,13},{133,0, +609},{133,11,624},{5,11,783},{7,11,1998},{135,11,2047},{133,10,525},{132,0,367}, +{132,11,594},{5,10,493},{134,0,528},{4,10,174},{135,10,911},{8,10,417},{137,10, +782},{132,0,694},{7,0,548},{137,0,58},{4,10,32},{5,10,215},{6,10,269},{7,10,1782 +},{7,10,1892},{10,10,16},{11,10,822},{11,10,954},{141,10,481},{140,0,687},{7,0, +1749},{136,10,477},{132,11,569},{133,10,308},{135,10,1088},{4,0,661},{138,0,1004 +},{5,11,37},{6,11,39},{6,11,451},{7,11,218},{7,11,667},{7,11,1166},{7,11,1687},{ +8,11,662},{144,11,2},{5,10,126},{8,10,297},{9,0,445},{9,10,366},{12,0,53},{12,10 +,374},{141,0,492},{7,10,1551},{139,10,361},{148,0,74},{134,11,508},{135,0,213},{ +132,10,175},{132,10,685},{6,0,760},{6,0,834},{134,0,1248},{7,11,453},{7,11,635}, +{7,11,796},{8,11,331},{9,11,328},{9,11,330},{9,11,865},{10,11,119},{10,11,235},{ +11,11,111},{11,11,129},{11,11,240},{12,11,31},{12,11,66},{12,11,222},{12,11,269} +,{12,11,599},{12,11,689},{13,11,186},{13,11,364},{142,11,345},{7,0,1672},{139,0, +189},{133,10,797},{133,10,565},{6,0,1548},{6,11,98},{7,11,585},{135,11,702},{9,0 +,968},{15,0,192},{149,0,56},{4,10,252},{6,11,37},{7,10,1068},{7,11,299},{7,11, +1666},{8,11,195},{8,11,316},{9,11,178},{9,11,276},{9,11,339},{9,11,536},{10,10, +434},{10,11,102},{10,11,362},{10,11,785},{11,10,228},{11,10,426},{11,11,55},{11, +11,149},{11,11,773},{13,10,231},{13,11,416},{13,11,419},{14,11,38},{14,11,41},{ +14,11,210},{18,10,106},{148,10,87},{4,0,751},{11,0,390},{140,0,32},{4,0,409},{ +133,0,78},{11,11,458},{12,11,15},{140,11,432},{5,10,231},{7,0,1602},{7,10,601},{ +9,10,277},{9,10,674},{10,0,257},{10,0,698},{10,10,178},{10,10,418},{10,10,509},{ +11,0,544},{11,0,585},{11,10,531},{12,0,212},{12,10,113},{12,10,475},{13,0,307},{ +13,10,99},{142,10,428},{6,0,473},{145,0,105},{5,11,645},{6,0,1949},{143,0,156},{ +7,10,1591},{144,10,43},{135,0,1779},{135,10,1683},{4,11,290},{135,11,1356},{134, +0,763},{6,11,70},{7,11,1292},{10,11,762},{139,11,288},{142,0,29},{140,11,428},{7 +,0,883},{7,11,131},{7,11,422},{8,11,210},{140,11,573},{134,0,488},{4,10,399},{5, +10,119},{5,10,494},{7,10,751},{137,10,556},{133,0,617},{132,11,936},{139,0,50},{ +7,0,1518},{139,0,694},{137,0,785},{4,0,546},{135,0,2042},{7,11,716},{13,11,97},{ +141,11,251},{132,11,653},{145,0,22},{134,0,1016},{4,0,313},{133,0,577},{136,11, +657},{8,0,184},{141,0,433},{135,0,935},{6,0,720},{9,0,114},{146,11,80},{7,10,594 +},{7,10,851},{7,10,1858},{9,10,411},{9,10,574},{9,10,666},{9,10,737},{10,10,346} +,{10,10,712},{11,10,246},{11,10,432},{11,10,517},{11,10,647},{11,10,679},{11,10, +727},{12,0,186},{12,0,292},{12,10,304},{12,10,305},{12,10,323},{12,10,483},{12, +10,572},{12,10,593},{12,10,602},{13,10,95},{13,10,101},{13,10,171},{13,10,315},{ +13,10,378},{13,10,425},{13,10,475},{14,0,100},{14,10,63},{14,10,380},{14,10,384} +,{15,10,133},{18,0,70},{18,10,112},{148,10,72},{135,10,1093},{135,11,1836},{132, +10,679},{137,10,203},{11,0,402},{12,0,109},{12,0,431},{13,0,179},{13,0,206},{14, +0,217},{16,0,3},{148,0,53},{7,11,1368},{8,11,232},{8,11,361},{10,11,682},{138,11 +,742},{137,10,714},{5,0,886},{6,0,46},{6,0,1790},{7,0,14},{7,0,732},{7,0,1654},{ +8,0,95},{8,0,327},{8,0,616},{9,0,892},{9,11,534},{10,0,598},{10,0,769},{11,0,134 +},{11,0,747},{12,0,378},{142,0,97},{4,0,969},{136,10,825},{137,11,27},{6,0,727}, +{142,11,12},{133,0,1021},{134,0,1190},{134,11,1657},{5,10,143},{5,10,769},{6,10, +1760},{7,10,682},{7,10,1992},{136,10,736},{132,0,153},{135,11,127},{133,0,798},{ +132,0,587},{6,0,598},{7,0,42},{8,0,695},{10,0,212},{11,0,158},{14,0,196},{145,0, +85},{133,10,860},{6,0,1929},{134,0,1933},{5,0,957},{5,0,1008},{6,10,422},{7,10,0 +},{7,10,1544},{8,11,364},{9,0,577},{11,10,990},{12,0,141},{12,10,453},{13,10,47} +,{141,10,266},{134,0,1319},{4,0,129},{135,0,465},{7,0,470},{7,0,1057},{7,0,1201} +,{9,0,755},{11,0,906},{140,0,527},{7,0,908},{146,0,7},{5,0,148},{136,0,450},{5, +10,515},{137,10,131},{7,10,1605},{11,10,962},{146,10,139},{132,10,646},{134,0, +1166},{4,10,396},{7,10,728},{9,10,117},{13,10,202},{148,10,51},{6,10,121},{6,10, +124},{6,10,357},{7,10,1138},{7,10,1295},{8,10,162},{139,10,655},{14,0,374},{142, +11,374},{138,0,253},{139,0,1003},{5,11,909},{9,11,849},{138,11,805},{133,10,237} +,{7,11,525},{7,11,1579},{8,11,497},{136,11,573},{137,0,46},{132,0,879},{134,0, +806},{135,0,1868},{6,0,1837},{134,0,1846},{6,0,730},{134,0,881},{7,0,965},{7,0, +1460},{7,0,1604},{7,11,193},{7,11,397},{7,11,1105},{8,11,124},{8,11,619},{9,11, +305},{10,11,264},{11,11,40},{12,11,349},{13,11,134},{13,11,295},{14,11,155},{15, +11,120},{146,11,105},{136,0,506},{143,0,10},{4,11,262},{7,10,571},{7,10,1877},{7 +,11,342},{10,10,366},{141,11,23},{133,11,641},{9,10,513},{10,0,22},{10,10,39},{ +12,10,122},{140,10,187},{135,11,1431},{150,11,49},{4,11,99},{6,11,250},{6,11,346 +},{8,11,127},{138,11,81},{6,0,2014},{8,0,928},{10,0,960},{10,0,979},{140,0,996}, +{134,0,296},{132,11,915},{5,11,75},{9,11,517},{10,11,470},{12,11,155},{141,11, +224},{137,10,873},{4,0,854},{140,11,18},{134,0,587},{7,10,107},{7,10,838},{8,10, +550},{138,10,401},{11,0,636},{11,10,588},{11,10,864},{11,10,968},{15,0,145},{15, +10,160},{17,0,34},{19,0,50},{151,0,20},{135,11,216},{7,0,982},{10,0,32},{143,0, +56},{133,10,768},{133,11,954},{6,11,304},{7,11,1114},{8,11,418},{10,11,345},{11, +11,341},{11,11,675},{141,11,40},{9,11,410},{139,11,425},{136,0,941},{4,10,894},{ +133,0,435},{5,0,85},{6,0,419},{7,0,134},{7,0,305},{7,0,361},{7,0,1337},{8,0,71}, +{140,0,519},{140,0,688},{135,0,740},{5,0,691},{7,0,345},{9,0,94},{140,0,169},{5, +0,183},{6,0,582},{10,0,679},{140,0,435},{134,11,14},{6,0,945},{135,0,511},{134, +11,1708},{5,11,113},{6,11,243},{7,11,1865},{11,11,161},{16,11,37},{145,11,99},{ +132,11,274},{137,0,539},{6,10,272},{7,0,1993},{136,0,684},{6,0,659},{134,0,982}, +{4,10,9},{5,10,128},{7,10,368},{11,10,480},{148,10,3},{134,0,583},{132,0,803},{ +133,0,704},{4,0,179},{5,0,198},{133,0,697},{7,0,347},{7,0,971},{7,11,166},{8,0, +181},{138,0,711},{136,10,682},{4,10,2},{7,10,545},{7,10,894},{136,11,521},{135,0 +,481},{132,0,243},{5,0,203},{7,0,19},{7,0,71},{7,0,113},{10,0,405},{11,0,357},{ +142,0,240},{5,11,725},{5,11,727},{135,11,1811},{6,0,826},{137,11,304},{7,0,1450} +,{139,0,99},{133,11,654},{134,0,492},{5,0,134},{6,0,408},{6,0,495},{6,11,273},{7 +,0,1593},{10,11,188},{13,11,377},{146,11,77},{9,10,769},{140,10,185},{135,11,410 +},{142,0,4},{4,0,665},{134,11,1785},{4,0,248},{7,0,137},{137,0,349},{5,10,530},{ +142,10,113},{7,0,1270},{139,0,612},{132,11,780},{5,0,371},{135,0,563},{135,0,826 +},{6,0,1535},{23,0,21},{151,0,23},{4,0,374},{7,0,547},{7,0,1700},{7,0,1833},{139 +,0,858},{133,10,556},{7,11,612},{8,11,545},{8,11,568},{8,11,642},{9,11,717},{10, +11,541},{10,11,763},{11,11,449},{12,11,489},{13,11,153},{13,11,296},{14,11,138}, +{14,11,392},{15,11,50},{16,11,6},{16,11,12},{148,11,9},{9,0,311},{141,0,42},{8, +10,16},{140,10,568},{6,0,1968},{6,0,2027},{138,0,991},{6,0,1647},{7,0,1552},{7,0 +,2010},{9,0,494},{137,0,509},{133,11,948},{6,10,186},{137,10,426},{134,0,769},{ +134,0,642},{132,10,585},{6,0,123},{7,0,214},{9,0,728},{10,0,157},{11,0,346},{11, +0,662},{143,0,106},{142,11,381},{135,0,1435},{4,11,532},{5,11,706},{135,11,662}, +{5,11,837},{134,11,1651},{4,10,93},{5,10,252},{6,10,229},{7,10,291},{9,10,550},{ +139,10,644},{148,0,79},{137,10,749},{134,0,1425},{137,10,162},{4,11,362},{7,11, +52},{7,11,303},{140,11,166},{132,10,381},{4,11,330},{7,11,933},{7,11,2012},{136, +11,292},{135,11,767},{4,0,707},{5,0,588},{6,0,393},{13,0,106},{18,0,49},{147,0, +41},{6,0,211},{7,0,1690},{11,0,486},{140,0,369},{137,11,883},{4,11,703},{135,11, +207},{4,0,187},{5,0,184},{5,0,690},{7,0,1869},{10,0,756},{139,0,783},{132,11,571 +},{134,0,1382},{5,0,175},{6,10,77},{6,10,157},{7,10,974},{7,10,1301},{7,10,1339} +,{7,10,1490},{7,10,1873},{137,10,628},{134,0,1493},{5,11,873},{133,11,960},{134, +0,1007},{12,11,93},{12,11,501},{13,11,362},{14,11,151},{15,11,40},{15,11,59},{16 +,11,46},{17,11,25},{18,11,14},{18,11,134},{19,11,25},{19,11,69},{20,11,16},{20, +11,19},{20,11,66},{21,11,23},{21,11,25},{150,11,42},{11,10,919},{141,10,409},{ +134,0,219},{5,0,582},{6,0,1646},{7,0,99},{7,0,1962},{7,0,1986},{8,0,515},{8,0, +773},{9,0,23},{9,0,491},{12,0,620},{142,0,93},{133,0,851},{5,11,33},{134,11,470} +,{135,11,1291},{134,0,1278},{135,11,1882},{135,10,1489},{132,0,1000},{138,0,982} +,{8,0,762},{8,0,812},{137,0,910},{6,11,47},{7,11,90},{7,11,664},{7,11,830},{7,11 +,1380},{7,11,2025},{8,11,448},{136,11,828},{4,0,98},{4,0,940},{6,0,1819},{6,0, +1834},{6,0,1841},{7,0,1365},{8,0,859},{8,0,897},{8,0,918},{8,10,398},{9,0,422},{ +9,0,670},{9,10,681},{10,0,775},{10,0,894},{10,0,909},{10,0,910},{10,0,935},{11,0 +,210},{11,10,632},{12,0,750},{12,0,755},{13,0,26},{13,0,457},{13,0,476},{16,0, +100},{16,0,109},{18,0,173},{146,0,175},{9,11,417},{137,11,493},{136,10,645},{138 +,0,906},{134,0,1730},{134,10,20},{133,11,1019},{134,0,1185},{8,10,769},{138,0,40 +},{6,11,208},{137,0,147},{140,0,650},{5,0,209},{6,0,30},{11,0,56},{139,0,305},{ +132,0,553},{138,11,344},{6,11,68},{7,11,398},{7,11,448},{7,11,1629},{7,11,1813}, +{8,11,387},{8,11,442},{9,11,710},{10,11,282},{138,11,722},{5,0,597},{14,0,20},{ +142,11,20},{135,0,1614},{135,10,1757},{4,0,150},{5,0,303},{6,0,327},{135,10,937} +,{7,10,1652},{16,0,49},{144,11,49},{8,0,192},{10,0,78},{141,0,359},{135,0,786},{ +143,0,134},{6,0,1638},{7,0,79},{7,0,496},{9,0,138},{10,0,336},{11,0,12},{12,0, +412},{12,0,440},{142,0,305},{136,11,491},{4,10,579},{5,10,226},{5,10,323},{135, +10,960},{7,0,204},{7,0,415},{8,0,42},{10,0,85},{139,0,564},{132,0,614},{4,11,403 +},{5,11,441},{7,11,450},{11,11,101},{12,11,193},{141,11,430},{135,11,1927},{135, +11,1330},{4,0,3},{5,0,247},{5,0,644},{7,0,744},{7,0,1207},{7,0,1225},{7,0,1909}, +{146,0,147},{136,0,942},{4,0,1019},{134,0,2023},{5,10,973},{133,11,679},{5,0,285 +},{9,0,67},{13,0,473},{143,0,82},{7,11,328},{137,11,326},{151,0,8},{6,10,135},{ +135,10,1176},{135,11,1128},{134,0,1309},{135,11,1796},{135,10,314},{4,11,574},{7 +,11,350},{7,11,1024},{8,11,338},{9,11,677},{10,11,808},{139,11,508},{7,11,818},{ +17,11,14},{17,11,45},{18,11,75},{148,11,18},{146,10,4},{135,11,1081},{4,0,29},{6 +,0,532},{7,0,1628},{7,0,1648},{9,0,350},{10,0,433},{11,0,97},{11,0,557},{11,0, +745},{12,0,289},{12,0,335},{12,0,348},{12,0,606},{13,0,116},{13,0,233},{13,0,466 +},{14,0,181},{14,0,209},{14,0,232},{14,0,236},{14,0,300},{16,0,41},{148,0,97},{6 +,10,281},{7,0,318},{8,10,282},{8,10,480},{8,10,499},{9,10,198},{10,10,143},{10, +10,169},{10,10,211},{10,10,417},{10,10,574},{11,10,147},{11,10,395},{12,10,75},{ +12,10,407},{12,10,608},{13,10,500},{142,10,251},{135,11,1676},{135,11,2037},{135 +,0,1692},{5,0,501},{7,0,1704},{9,0,553},{11,0,520},{12,0,557},{141,0,249},{6,0, +1527},{14,0,324},{14,11,324},{15,0,55},{15,0,80},{15,11,55},{143,11,80},{135,10, +1776},{8,0,988},{137,11,297},{132,10,419},{142,0,223},{139,11,234},{7,0,1123},{ +12,0,508},{14,0,102},{14,0,226},{144,0,57},{4,10,138},{7,10,1012},{7,10,1280},{ +137,10,76},{5,10,29},{7,0,1764},{140,10,638},{134,0,2015},{134,0,1599},{138,11, +56},{6,11,306},{7,11,1140},{7,11,1340},{8,11,133},{138,11,449},{139,11,1011},{6, +10,1710},{135,10,2038},{7,11,1763},{140,11,310},{4,10,17},{5,10,23},{6,0,129},{7 +,10,995},{11,10,383},{11,10,437},{12,10,460},{140,10,532},{5,11,329},{136,11,260 +},{133,10,862},{132,0,534},{6,0,811},{135,0,626},{132,11,657},{4,0,25},{5,0,60}, +{6,0,504},{7,0,614},{7,0,1155},{12,0,0},{152,11,7},{7,0,1248},{11,0,621},{139,0, +702},{137,0,321},{8,10,70},{12,10,171},{141,10,272},{10,10,233},{139,10,76},{4,0 +,379},{6,10,442},{135,0,1397},{5,11,66},{7,11,1896},{136,11,288},{134,11,1643},{ +134,10,1709},{4,11,21},{5,11,91},{5,11,570},{5,11,648},{5,11,750},{5,11,781},{6, +11,54},{6,11,112},{6,11,402},{6,11,1732},{7,11,315},{7,11,749},{7,11,1347},{7,11 +,1900},{9,11,78},{9,11,508},{10,11,611},{11,11,510},{11,11,728},{13,11,36},{14, +11,39},{16,11,83},{17,11,124},{148,11,30},{4,0,118},{6,0,274},{6,0,361},{7,0,75} +,{141,0,441},{10,11,322},{10,11,719},{139,11,407},{147,10,119},{12,11,549},{14, +11,67},{147,11,60},{11,10,69},{12,10,105},{12,10,117},{13,10,213},{14,10,13},{14 +,10,62},{14,10,177},{14,10,421},{15,10,19},{146,10,141},{9,0,841},{137,10,309},{ +7,10,608},{7,10,976},{8,11,125},{8,11,369},{8,11,524},{9,10,146},{10,10,206},{10 +,10,596},{10,11,486},{11,11,13},{11,11,381},{11,11,736},{11,11,766},{11,11,845}, +{13,10,218},{13,11,114},{13,11,292},{14,10,153},{142,11,47},{7,11,759},{140,0, +693},{5,0,314},{6,0,221},{7,0,419},{10,0,650},{11,0,396},{12,0,156},{13,0,369},{ +14,0,333},{145,0,47},{6,11,1684},{6,11,1731},{7,11,356},{7,11,1932},{8,11,54},{8 +,11,221},{9,11,225},{9,11,356},{10,11,77},{10,11,446},{10,11,731},{12,11,404},{ +141,11,491},{132,11,375},{4,10,518},{135,10,1136},{4,0,913},{4,11,411},{11,11, +643},{140,11,115},{4,11,80},{133,11,44},{8,10,689},{137,10,863},{138,0,880},{4, +10,18},{7,10,145},{7,10,444},{7,10,1278},{8,10,49},{8,10,400},{9,10,71},{9,10, +250},{10,10,459},{12,10,160},{144,10,24},{136,0,475},{5,0,1016},{5,11,299},{135, +11,1083},{7,0,602},{8,0,179},{10,0,781},{140,0,126},{6,0,329},{138,0,111},{135,0 +,1864},{4,11,219},{7,11,1761},{137,11,86},{6,0,1888},{6,0,1892},{6,0,1901},{6,0, +1904},{9,0,953},{9,0,985},{9,0,991},{9,0,1001},{12,0,818},{12,0,846},{12,0,847}, +{12,0,861},{12,0,862},{12,0,873},{12,0,875},{12,0,877},{12,0,879},{12,0,881},{12 +,0,884},{12,0,903},{12,0,915},{12,0,926},{12,0,939},{15,0,182},{15,0,219},{15,0, +255},{18,0,191},{18,0,209},{18,0,211},{149,0,41},{5,11,328},{135,11,918},{137,0, +780},{12,0,82},{143,0,36},{133,10,1010},{5,0,821},{134,0,1687},{133,11,514},{132 +,0,956},{134,0,1180},{5,10,87},{7,10,313},{7,10,1103},{10,0,112},{10,10,582},{11 +,10,389},{11,10,813},{12,10,385},{13,10,286},{14,10,124},{146,10,108},{5,0,71},{ +7,0,1407},{9,0,704},{10,0,261},{10,0,619},{11,0,547},{11,0,619},{143,0,157},{4,0 +,531},{5,0,455},{5,11,301},{6,11,571},{14,11,49},{146,11,102},{132,10,267},{6,0, +385},{7,0,2008},{9,0,337},{138,0,517},{133,11,726},{133,11,364},{4,11,76},{7,11, +1550},{9,11,306},{9,11,430},{9,11,663},{10,11,683},{11,11,427},{11,11,753},{12, +11,334},{12,11,442},{14,11,258},{14,11,366},{143,11,131},{6,0,1865},{6,0,1879},{ +6,0,1881},{6,0,1894},{6,0,1908},{9,0,915},{9,0,926},{9,0,940},{9,0,943},{9,0,966 +},{9,0,980},{9,0,989},{9,0,1005},{9,0,1010},{12,0,813},{12,0,817},{12,0,840},{12 +,0,843},{12,0,855},{12,0,864},{12,0,871},{12,0,872},{12,0,899},{12,0,905},{12,0, +924},{15,0,171},{15,0,181},{15,0,224},{15,0,235},{15,0,251},{146,0,184},{137,11, +52},{5,0,16},{6,0,86},{6,0,603},{7,0,292},{7,0,561},{8,0,257},{8,0,382},{9,0,721 +},{9,0,778},{11,0,581},{140,0,466},{4,0,486},{5,0,491},{135,10,1121},{4,0,72},{6 +,0,265},{135,0,1300},{135,11,1183},{10,10,249},{139,10,209},{132,10,561},{137,11 +,519},{4,10,760},{4,11,656},{135,11,779},{9,10,154},{140,10,485},{135,11,1793},{ +135,11,144},{136,10,255},{133,0,621},{4,10,368},{135,10,641},{135,11,1373},{7,11 +,554},{7,11,605},{141,11,10},{137,0,234},{5,0,815},{6,0,1688},{134,0,1755},{5,11 +,838},{5,11,841},{134,11,1649},{7,0,1987},{7,0,2040},{136,0,743},{133,11,1012},{ +6,0,197},{136,0,205},{6,0,314},{134,11,314},{144,11,53},{6,11,251},{7,11,365},{7 +,11,1357},{7,11,1497},{8,11,154},{141,11,281},{133,11,340},{6,0,452},{7,0,312},{ +138,0,219},{138,0,589},{4,0,333},{9,0,176},{12,0,353},{141,0,187},{9,10,92},{147 +,10,91},{134,0,1110},{11,0,47},{139,11,495},{6,10,525},{8,10,806},{9,10,876},{ +140,10,284},{8,11,261},{9,11,144},{9,11,466},{10,11,370},{12,11,470},{13,11,144} +,{142,11,348},{137,11,897},{6,11,248},{8,0,863},{8,0,864},{8,0,868},{8,0,884},{9 +,11,546},{10,0,866},{10,0,868},{10,0,873},{10,0,911},{10,0,912},{10,0,944},{10, +11,535},{11,11,681},{12,0,727},{141,11,135},{6,0,300},{135,0,1515},{134,0,1237}, +{139,10,958},{133,10,594},{140,11,250},{134,0,1685},{134,11,567},{7,0,135},{8,0, +7},{8,0,62},{9,0,243},{10,0,658},{10,0,697},{11,0,456},{139,0,756},{9,0,395},{ +138,0,79},{6,10,1641},{136,10,820},{4,10,302},{135,10,1766},{134,11,174},{135,10 +,1313},{135,0,631},{134,10,1674},{134,11,395},{138,0,835},{7,0,406},{7,0,459},{8 +,0,606},{139,0,726},{134,11,617},{134,0,979},{6,10,389},{7,10,149},{9,10,142},{ +138,10,94},{5,11,878},{133,11,972},{6,10,8},{7,10,1881},{8,10,91},{136,11,511},{ +133,0,612},{132,11,351},{4,0,372},{7,0,482},{8,0,158},{9,0,602},{9,0,615},{10,0, +245},{10,0,678},{10,0,744},{11,0,248},{139,0,806},{5,0,854},{135,0,1991},{132,11 +,286},{135,11,344},{7,11,438},{7,11,627},{7,11,1516},{8,11,40},{9,11,56},{9,11, +294},{10,11,30},{10,11,259},{11,11,969},{146,11,148},{135,0,1492},{5,11,259},{7, +11,414},{7,11,854},{142,11,107},{135,10,1746},{6,0,833},{134,0,998},{135,10,24}, +{6,0,750},{135,0,1739},{4,10,503},{135,10,1661},{5,10,130},{7,10,1314},{9,10,610 +},{10,10,718},{11,10,601},{11,10,819},{11,10,946},{140,10,536},{10,10,149},{11, +10,280},{142,10,336},{132,11,738},{135,10,1946},{5,0,195},{135,0,1685},{7,0,1997 +},{8,0,730},{139,0,1006},{151,11,17},{133,11,866},{14,0,463},{14,0,470},{150,0, +61},{4,10,392},{5,0,751},{7,10,1597},{8,0,266},{139,0,578},{5,10,433},{9,10,633} +,{139,10,629},{135,0,821},{6,0,715},{134,0,1325},{133,11,116},{4,11,457},{134,0, +868},{134,0,959},{6,10,234},{138,11,199},{7,0,1053},{7,10,1950},{8,10,680},{11, +10,817},{147,10,88},{7,10,1222},{138,10,386},{5,0,950},{5,0,994},{6,0,351},{134, +0,1124},{134,0,1081},{6,10,5},{7,0,1595},{11,10,249},{12,10,313},{16,10,66},{145 +,10,26},{148,0,59},{5,11,527},{6,11,189},{135,11,859},{5,10,963},{6,10,1773},{11 +,11,104},{11,11,554},{15,11,60},{143,11,125},{135,0,47},{137,0,684},{134,11,116} +,{134,0,1606},{134,0,777},{7,0,1020},{8,10,509},{136,10,792},{135,0,1094},{132,0 +,350},{133,11,487},{4,11,86},{5,11,667},{5,11,753},{6,11,316},{6,11,455},{135,11 +,946},{7,0,1812},{13,0,259},{13,0,356},{14,0,242},{147,0,114},{132,10,931},{133, +0,967},{4,0,473},{7,0,623},{8,0,808},{9,0,871},{9,0,893},{11,0,38},{11,0,431},{ +12,0,112},{12,0,217},{12,0,243},{12,0,562},{12,0,663},{12,0,683},{13,0,141},{13, +0,197},{13,0,227},{13,0,406},{13,0,487},{14,0,156},{14,0,203},{14,0,224},{14,0, +256},{18,0,58},{150,0,0},{138,0,286},{7,10,943},{139,10,614},{135,10,1837},{150, +11,45},{132,0,798},{4,0,222},{7,0,286},{136,0,629},{4,11,79},{7,11,1773},{10,11, +450},{11,11,589},{13,11,332},{13,11,493},{14,11,183},{14,11,334},{14,11,362},{14 +,11,368},{14,11,376},{14,11,379},{19,11,90},{19,11,103},{19,11,127},{148,11,90}, +{4,10,90},{5,0,337},{5,10,545},{7,10,754},{9,10,186},{10,10,72},{10,10,782},{11, +0,513},{11,0,889},{11,0,961},{11,10,577},{11,10,610},{12,0,461},{12,10,354},{12, +10,362},{12,10,595},{13,0,79},{143,0,121},{141,0,306},{136,0,146},{7,0,1646},{9, +10,329},{11,10,254},{141,11,124},{4,0,465},{135,0,1663},{132,0,525},{133,11,663} +,{9,10,187},{10,0,299},{11,10,1016},{17,10,44},{146,0,74},{4,10,506},{7,0,165},{ +7,0,919},{136,10,517},{5,10,295},{135,10,1680},{133,11,846},{134,0,1064},{5,11, +378},{7,11,1402},{7,11,1414},{8,11,465},{9,11,286},{10,11,185},{10,11,562},{10, +11,635},{11,11,31},{11,11,393},{12,11,456},{13,11,312},{18,11,65},{18,11,96},{ +147,11,89},{132,0,596},{7,10,987},{9,10,688},{10,10,522},{11,10,788},{140,10,566 +},{4,11,648},{6,0,82},{6,10,1775},{7,0,138},{7,0,517},{7,0,1741},{139,0,238},{7, +0,1233},{7,10,700},{7,10,940},{8,10,514},{9,10,116},{9,10,535},{10,10,118},{11, +10,107},{11,10,148},{11,10,922},{12,10,254},{12,10,421},{142,10,238},{4,0,962},{ +6,0,1824},{8,0,894},{12,0,708},{12,0,725},{14,0,451},{20,0,94},{22,0,59},{150,0, +62},{5,11,945},{6,11,1656},{6,11,1787},{7,11,167},{8,11,824},{9,11,391},{10,11, +375},{139,11,185},{5,0,495},{7,0,834},{9,0,733},{139,0,378},{4,10,743},{135,11, +1273},{6,0,1204},{7,11,1645},{8,11,352},{137,11,249},{139,10,292},{133,0,559},{ +132,11,152},{7,10,1283},{9,0,499},{9,10,227},{10,0,341},{11,10,325},{11,10,408}, +{14,10,180},{15,0,144},{18,10,47},{147,0,49},{6,0,21},{6,0,1737},{7,0,1444},{136 +,0,224},{133,11,1006},{5,10,81},{7,0,1446},{7,10,146},{7,10,1342},{8,10,53},{8, +10,561},{8,10,694},{8,10,754},{9,0,97},{9,10,115},{9,10,894},{10,10,462},{10,10, +813},{11,10,230},{11,10,657},{11,10,699},{11,10,748},{12,10,119},{12,10,200},{12 +,10,283},{14,10,273},{145,0,15},{5,10,408},{137,10,747},{135,11,431},{135,11,832 +},{6,0,729},{134,0,953},{4,0,727},{5,11,351},{7,11,264},{8,0,565},{136,11,565},{ +134,0,1948},{5,0,519},{5,11,40},{7,11,598},{7,11,1638},{8,11,78},{9,11,166},{9, +11,640},{9,11,685},{9,11,773},{11,11,215},{13,11,65},{14,11,172},{14,11,317},{ +145,11,6},{8,11,60},{9,11,343},{139,11,769},{137,11,455},{134,0,1193},{140,0,790 +},{7,11,1951},{8,11,765},{8,11,772},{140,11,671},{7,11,108},{8,11,219},{8,11,388 +},{9,11,639},{9,11,775},{11,11,275},{140,11,464},{132,11,468},{7,10,30},{8,10,86 +},{8,10,315},{8,10,700},{9,10,576},{9,10,858},{11,10,310},{11,10,888},{11,10,904 +},{12,10,361},{141,10,248},{5,11,15},{6,11,56},{7,11,1758},{8,11,500},{9,11,730} +,{11,11,331},{13,11,150},{142,11,282},{4,0,402},{7,0,2},{8,0,323},{136,0,479},{ +138,10,839},{11,0,580},{142,0,201},{5,0,59},{135,0,672},{137,10,617},{146,0,34}, +{134,11,1886},{4,0,961},{136,0,896},{5,11,205},{6,0,1285},{6,11,438},{137,11,711 +},{134,10,428},{7,10,524},{8,10,169},{8,10,234},{9,10,480},{138,10,646},{148,0, +46},{141,0,479},{133,11,534},{6,0,2019},{134,10,1648},{4,0,85},{7,0,549},{7,10, +1205},{138,10,637},{4,0,663},{5,0,94},{7,11,235},{7,11,1475},{15,11,68},{146,11, +120},{6,11,443},{9,11,237},{9,11,571},{9,11,695},{10,11,139},{11,11,715},{12,11, +417},{141,11,421},{132,0,783},{4,0,682},{8,0,65},{9,10,39},{10,10,166},{11,10, +918},{12,10,635},{20,10,10},{22,10,27},{22,10,43},{150,10,52},{6,0,11},{135,0, +187},{132,0,522},{4,0,52},{135,0,661},{4,0,383},{133,0,520},{135,11,546},{11,0, +343},{142,0,127},{4,11,578},{7,10,157},{7,11,624},{7,11,916},{8,10,279},{10,11, +256},{11,11,87},{139,11,703},{134,10,604},{4,0,281},{5,0,38},{7,0,194},{7,0,668} +,{7,0,1893},{137,0,397},{7,10,945},{11,10,713},{139,10,744},{139,10,1022},{9,0, +635},{139,0,559},{5,11,923},{7,11,490},{12,11,553},{13,11,100},{14,11,118},{143, +11,75},{132,0,975},{132,10,567},{137,10,859},{7,10,1846},{7,11,1846},{8,10,628}, +{136,11,628},{148,0,116},{138,11,750},{14,0,51},{14,11,51},{15,11,7},{148,11,20} +,{132,0,858},{134,0,1075},{4,11,924},{133,10,762},{136,0,535},{133,0,448},{10,10 +,784},{141,10,191},{133,10,298},{7,0,610},{135,0,1501},{7,10,633},{7,10,905},{7, +10,909},{7,10,1538},{9,10,767},{140,10,636},{4,11,265},{7,11,807},{135,11,950},{ +5,11,93},{12,11,267},{144,11,26},{136,0,191},{139,10,301},{135,10,1970},{135,0, +267},{4,0,319},{5,0,699},{138,0,673},{6,0,336},{7,0,92},{7,0,182},{8,0,453},{8,0 +,552},{9,0,204},{9,0,285},{10,0,99},{11,0,568},{11,0,950},{12,0,94},{12,10,644}, +{16,0,20},{16,0,70},{16,10,90},{147,0,55},{6,0,551},{7,0,1308},{7,10,845},{7,11, +994},{8,10,160},{137,10,318},{19,11,1},{19,11,26},{150,11,9},{7,0,1406},{9,0,218 +},{141,0,222},{5,0,256},{138,0,69},{5,11,233},{5,11,320},{6,11,140},{7,11,330},{ +136,11,295},{6,0,1980},{136,0,952},{4,0,833},{137,11,678},{133,11,978},{4,11,905 +},{6,11,1701},{137,11,843},{138,10,735},{136,10,76},{17,0,39},{148,0,36},{18,0, +81},{146,11,81},{14,0,352},{17,0,53},{18,0,146},{18,0,152},{19,0,11},{150,0,54}, +{135,0,634},{138,10,841},{132,0,618},{4,0,339},{4,11,275},{7,0,259},{12,11,376}, +{145,0,73},{132,11,509},{7,11,273},{139,11,377},{4,0,759},{9,10,804},{141,0,169} +,{6,10,96},{135,10,1426},{4,10,651},{133,10,289},{7,0,1075},{8,10,35},{9,10,511} +,{10,10,767},{147,10,118},{6,0,649},{6,0,670},{136,0,482},{5,0,336},{6,0,341},{6 +,0,478},{6,0,1763},{136,0,386},{5,11,802},{7,11,2021},{8,11,805},{14,11,94},{15, +11,65},{16,11,4},{16,11,77},{16,11,80},{145,11,5},{5,11,167},{5,11,899},{6,0, +1035},{6,11,410},{137,11,777},{134,11,1705},{5,0,924},{133,0,969},{132,10,704},{ +135,0,73},{135,11,10},{135,10,1078},{5,11,11},{6,11,117},{6,11,485},{7,11,1133}, +{9,11,582},{9,11,594},{11,11,21},{11,11,818},{12,11,535},{141,11,86},{135,0,1971 +},{4,11,264},{7,11,1067},{8,11,204},{8,11,385},{139,11,953},{6,0,1458},{135,0, +1344},{5,0,396},{134,0,501},{4,10,720},{133,10,306},{4,0,929},{5,0,799},{5,10, +431},{8,0,46},{136,0,740},{7,11,646},{7,11,1730},{11,11,446},{141,11,178},{5,10, +464},{6,10,236},{7,0,276},{7,10,696},{7,10,914},{7,10,1108},{7,10,1448},{9,10,15 +},{9,10,564},{10,10,14},{12,10,565},{13,10,449},{14,10,53},{15,10,13},{16,10,64} +,{145,10,41},{4,0,892},{133,0,770},{6,10,1767},{12,10,194},{145,10,107},{135,0, +158},{5,10,840},{138,11,608},{134,0,1432},{138,11,250},{8,11,794},{9,11,400},{10 +,11,298},{142,11,228},{151,0,25},{7,11,1131},{135,11,1468},{135,0,2001},{9,10, +642},{11,10,236},{142,10,193},{4,10,68},{5,10,634},{6,10,386},{7,10,794},{8,10, +273},{9,10,563},{10,10,105},{10,10,171},{11,10,94},{139,10,354},{136,11,724},{ +132,0,478},{11,11,512},{13,11,205},{19,11,30},{22,11,36},{151,11,19},{7,0,1461}, +{140,0,91},{6,11,190},{7,11,768},{135,11,1170},{4,0,602},{4,10,95},{7,10,416},{8 +,0,211},{139,10,830},{7,10,731},{13,10,20},{143,10,11},{6,0,1068},{135,0,1872},{ +4,0,13},{5,0,567},{7,0,1498},{7,11,1023},{9,0,124},{11,0,521},{140,0,405},{135,0 +,1006},{132,0,735},{138,0,812},{4,0,170},{135,0,323},{6,11,137},{9,11,75},{9,11, +253},{10,11,194},{138,11,444},{5,0,304},{5,10,864},{7,0,1403},{10,10,648},{11,10 +,671},{143,10,46},{135,11,1180},{133,10,928},{4,0,148},{133,0,742},{11,10,986},{ +140,10,682},{133,0,523},{135,11,1743},{7,0,730},{8,10,44},{9,10,884},{10,10,580} +,{11,10,399},{11,10,894},{15,10,122},{18,0,144},{147,0,61},{5,11,760},{7,11,542} +,{8,11,135},{136,11,496},{136,0,981},{133,0,111},{10,0,132},{11,0,191},{11,0,358 +},{139,0,460},{7,11,319},{7,11,355},{7,11,763},{10,11,389},{145,11,43},{134,0, +890},{134,0,1420},{136,11,557},{133,10,518},{133,0,444},{135,0,1787},{135,10, +1852},{8,0,123},{15,0,6},{144,0,7},{6,0,2041},{10,11,38},{139,11,784},{136,0,932 +},{5,0,937},{135,0,100},{4,11,58},{5,11,286},{6,0,995},{6,11,319},{7,11,402},{7, +11,1254},{7,11,1903},{8,11,356},{140,11,408},{4,11,389},{9,11,181},{9,11,255},{ +10,11,8},{10,11,29},{10,11,816},{11,11,311},{11,11,561},{12,11,67},{141,11,181}, +{138,0,255},{4,10,934},{5,0,138},{136,10,610},{4,0,965},{10,0,863},{138,0,898},{ +10,10,804},{138,10,832},{8,10,96},{9,10,36},{10,10,607},{11,10,423},{11,10,442}, +{12,0,631},{12,10,309},{14,10,199},{15,10,90},{145,10,110},{134,0,1394},{4,0,652 +},{8,0,320},{9,10,13},{9,10,398},{9,10,727},{10,10,75},{10,10,184},{10,10,230},{ +10,10,564},{10,10,569},{11,10,973},{12,10,70},{12,10,189},{13,10,57},{13,10,257} +,{22,0,6},{150,0,16},{6,0,897},{134,0,1333},{4,0,692},{133,0,321},{133,11,373},{ +135,0,922},{5,0,619},{133,0,698},{137,10,631},{5,10,345},{135,10,1016},{9,0,957} +,{9,0,1018},{12,0,828},{12,0,844},{12,0,897},{12,0,901},{12,0,943},{15,0,180},{ +18,0,197},{18,0,200},{18,0,213},{18,0,214},{146,0,226},{5,0,917},{134,0,1659},{ +135,0,1100},{134,0,1173},{134,0,1930},{5,0,251},{5,0,956},{8,0,268},{9,0,214},{ +146,0,142},{133,10,673},{137,10,850},{4,10,287},{133,10,1018},{132,11,672},{5,0, +346},{5,0,711},{8,0,390},{11,11,752},{139,11,885},{5,10,34},{10,10,724},{12,10, +444},{13,10,354},{18,10,32},{23,10,24},{23,10,31},{152,10,5},{4,11,710},{134,11, +606},{134,0,744},{134,10,382},{133,11,145},{4,10,329},{7,11,884},{140,11,124},{4 +,11,467},{5,11,405},{134,11,544},{9,10,846},{138,10,827},{133,0,624},{9,11,372}, +{15,11,2},{19,11,10},{147,11,18},{4,11,387},{135,11,1288},{5,0,783},{7,0,1998},{ +135,0,2047},{132,10,906},{136,10,366},{135,11,550},{4,10,123},{4,10,649},{5,10, +605},{7,10,1509},{136,10,36},{134,0,1125},{132,0,594},{133,10,767},{135,11,1227} +,{136,11,467},{4,11,576},{135,11,1263},{4,0,268},{7,0,1534},{135,11,1534},{4,10, +273},{5,10,658},{5,10,995},{5,11,919},{134,11,1673},{133,0,563},{134,10,72},{135 +,10,1345},{4,11,82},{5,11,333},{5,11,904},{6,11,207},{7,11,325},{7,11,1726},{8, +11,101},{10,11,778},{139,11,220},{5,0,37},{5,10,589},{6,0,39},{6,0,451},{7,0,218 +},{7,0,667},{7,0,1166},{7,0,1687},{8,0,662},{144,0,2},{134,0,1332},{133,11,903}, +{134,0,508},{5,10,117},{6,10,514},{6,10,541},{7,10,1164},{7,10,1436},{8,10,220}, +{8,10,648},{10,10,688},{11,10,560},{140,11,147},{6,11,555},{135,11,485},{133,10, +686},{7,0,453},{7,0,635},{7,0,796},{8,0,331},{9,0,330},{9,0,865},{10,0,119},{10, +0,235},{11,0,111},{11,0,129},{11,0,240},{12,0,31},{12,0,66},{12,0,222},{12,0,269 +},{12,0,599},{12,0,684},{12,0,689},{12,0,691},{142,0,345},{135,0,1834},{4,11,705 +},{7,11,615},{138,11,251},{136,11,345},{137,0,527},{6,0,98},{7,0,702},{135,0,991 +},{7,10,196},{10,10,765},{11,0,576},{11,10,347},{11,10,552},{11,10,790},{12,10, +263},{13,10,246},{13,10,270},{13,10,395},{14,0,74},{14,10,176},{14,10,190},{14, +10,398},{14,10,412},{15,10,32},{15,10,63},{16,10,88},{147,10,105},{134,11,90},{ +13,0,84},{141,0,122},{6,0,37},{7,0,299},{7,0,1666},{8,0,195},{8,0,316},{9,0,178} +,{9,0,276},{9,0,339},{9,0,536},{10,0,102},{10,0,362},{10,0,785},{11,0,55},{11,0, +149},{11,0,773},{13,0,416},{13,0,419},{14,0,38},{14,0,41},{142,0,210},{5,10,381} +,{135,10,1792},{7,11,813},{12,11,497},{141,11,56},{7,10,616},{138,10,413},{133,0 +,645},{6,11,125},{135,11,1277},{132,0,290},{6,0,70},{7,0,1292},{10,0,762},{139,0 +,288},{6,10,120},{7,10,1188},{7,10,1710},{8,10,286},{9,10,667},{11,10,592},{139, +10,730},{135,11,1784},{7,0,1315},{135,11,1315},{134,0,1955},{135,10,1146},{7,0, +131},{7,0,422},{8,0,210},{140,0,573},{4,10,352},{135,10,687},{139,0,797},{143,0, +38},{14,0,179},{15,0,151},{150,0,11},{4,10,192},{5,10,49},{6,10,200},{6,10,293}, +{6,10,1696},{135,0,488},{132,0,936},{135,11,703},{6,11,160},{7,11,1106},{9,11, +770},{10,11,618},{11,11,112},{140,11,413},{5,0,453},{134,0,441},{135,0,595},{132 +,10,650},{132,10,147},{6,0,991},{6,0,1182},{12,11,271},{145,11,109},{133,10,934} +,{140,11,221},{132,0,653},{7,0,505},{135,0,523},{134,0,903},{135,11,479},{7,11, +304},{9,11,646},{9,11,862},{10,11,262},{11,11,696},{12,11,208},{15,11,79},{147, +11,108},{146,0,80},{135,11,981},{142,0,432},{132,0,314},{137,11,152},{7,0,1368}, +{8,0,232},{8,0,361},{10,0,682},{138,0,742},{135,11,1586},{4,11,434},{9,0,534},{ +11,11,663},{12,11,210},{13,11,166},{13,11,310},{14,11,373},{147,11,43},{7,11, +1091},{135,11,1765},{6,11,550},{135,11,652},{137,0,27},{142,0,12},{4,10,637},{5, +11,553},{7,11,766},{138,11,824},{7,11,737},{8,11,298},{136,11,452},{7,0,736},{ +139,0,264},{134,0,1657},{133,11,292},{138,11,135},{6,0,844},{134,0,1117},{135,0, +127},{9,10,867},{138,10,837},{6,0,1184},{134,0,1208},{134,0,1294},{136,0,364},{6 +,0,1415},{6,10,170},{7,0,1334},{7,11,393},{8,10,395},{8,10,487},{10,11,603},{11, +0,125},{11,11,206},{141,10,147},{137,11,748},{4,11,912},{137,11,232},{4,10,535}, +{136,10,618},{137,0,792},{7,11,1973},{136,11,716},{135,11,98},{5,0,909},{9,0,849 +},{138,0,805},{4,0,630},{132,0,699},{5,11,733},{14,11,103},{150,10,23},{12,11, +158},{18,11,8},{19,11,62},{20,11,6},{22,11,4},{23,11,2},{151,11,9},{132,0,968},{ +132,10,778},{132,10,46},{5,10,811},{6,10,1679},{6,10,1714},{135,10,2032},{6,0, +1446},{7,10,1458},{9,10,407},{139,10,15},{6,10,34},{7,0,206},{7,0,397},{7,0,621} +,{7,0,640},{7,10,1089},{8,0,124},{8,0,619},{8,10,708},{8,10,721},{9,0,305},{9,0, +643},{9,10,363},{10,0,264},{10,0,628},{11,0,40},{12,0,349},{13,0,134},{13,0,295} +,{14,0,155},{15,0,120},{18,0,105},{148,10,98},{4,0,262},{5,0,641},{135,0,342},{ +137,11,72},{4,0,99},{6,0,250},{6,0,346},{8,0,127},{138,0,81},{132,0,915},{5,0,75 +},{9,0,517},{10,0,470},{12,0,155},{141,0,224},{132,10,462},{11,11,600},{11,11, +670},{141,11,245},{142,0,83},{5,10,73},{6,10,23},{134,10,338},{6,0,1031},{139,11 +,923},{7,11,164},{7,11,1571},{9,11,107},{140,11,225},{134,0,1470},{133,0,954},{6 +,0,304},{8,0,418},{10,0,345},{11,0,341},{139,0,675},{9,0,410},{139,0,425},{4,11, +27},{5,11,484},{5,11,510},{6,11,434},{7,11,1000},{7,11,1098},{8,11,2},{136,11, +200},{134,0,734},{140,11,257},{7,10,725},{8,10,498},{139,10,268},{134,0,1822},{ +135,0,1798},{135,10,773},{132,11,460},{4,11,932},{133,11,891},{134,0,14},{132,10 +,583},{7,10,1462},{8,11,625},{139,10,659},{5,0,113},{5,10,220},{6,0,243},{6,0, +1708},{7,0,1865},{11,0,161},{16,0,37},{145,0,99},{134,11,76},{5,11,461},{135,11, +1925},{140,0,69},{8,11,92},{137,11,221},{139,10,803},{132,10,544},{4,0,274},{134 +,0,922},{132,0,541},{5,0,627},{6,10,437},{6,10,564},{11,10,181},{141,10,183},{ +135,10,1192},{4,11,763},{135,0,166},{133,11,253},{134,0,849},{9,11,73},{10,11, +110},{14,11,185},{145,11,119},{5,11,212},{12,11,35},{141,11,382},{133,0,717},{ +137,0,304},{136,0,600},{133,0,654},{6,0,273},{10,0,188},{13,0,377},{146,0,77},{4 +,10,790},{5,10,273},{134,10,394},{132,0,543},{135,0,410},{11,0,98},{11,0,524},{ +141,0,87},{132,0,941},{135,11,1175},{4,0,250},{6,10,127},{7,0,1612},{7,10,1511}, +{8,10,613},{11,0,186},{12,0,133},{12,10,495},{12,10,586},{12,10,660},{12,10,668} +,{14,10,385},{15,10,118},{17,10,20},{146,10,98},{5,11,816},{134,0,1785},{134,0, +1339},{6,10,230},{7,0,961},{7,0,1085},{7,0,1727},{7,11,1727},{136,0,462},{7,10, +1954},{137,0,636},{132,0,780},{5,11,869},{5,11,968},{6,11,1626},{8,11,734},{136, +11,784},{4,11,542},{6,11,1716},{6,11,1727},{7,11,1082},{7,11,1545},{8,11,56},{8, +11,118},{8,11,412},{8,11,564},{9,11,888},{9,11,908},{10,11,50},{10,11,423},{11, +11,685},{11,11,697},{11,11,933},{12,11,299},{13,11,126},{13,11,136},{13,11,170}, +{141,11,190},{134,11,226},{4,11,232},{9,11,202},{10,11,474},{140,11,433},{137,11 +,500},{5,0,529},{136,10,68},{132,10,654},{4,10,156},{7,10,998},{7,10,1045},{7,10 +,1860},{9,10,48},{9,10,692},{11,10,419},{139,10,602},{6,11,108},{7,0,1276},{7,11 +,1003},{7,11,1181},{8,0,474},{8,11,343},{137,0,652},{7,11,1264},{7,11,1678},{11, +11,945},{12,11,341},{12,11,471},{140,11,569},{134,11,1712},{5,0,948},{12,0,468}, +{19,0,96},{148,0,24},{4,11,133},{7,11,711},{7,11,1298},{7,11,1585},{135,11,1929} +,{6,0,753},{140,0,657},{139,0,941},{6,11,99},{7,11,1808},{145,11,57},{6,11,574}, +{7,11,428},{7,11,1250},{10,11,669},{11,11,485},{11,11,840},{12,11,300},{142,11, +250},{4,0,532},{5,0,706},{135,0,662},{5,0,837},{6,0,1651},{139,0,985},{7,0,1861} +,{9,10,197},{10,10,300},{12,10,473},{13,10,90},{141,10,405},{137,11,252},{6,11, +323},{135,11,1564},{4,0,330},{4,0,863},{7,0,933},{7,0,2012},{7,11,461},{8,0,292} +,{8,11,775},{138,11,435},{132,10,606},{4,11,655},{7,11,850},{17,11,75},{146,11, +137},{135,0,767},{7,10,1978},{136,10,676},{132,0,641},{135,11,1559},{134,0,1233} +,{137,0,242},{4,10,361},{5,10,315},{145,0,114},{137,0,883},{132,10,461},{138,0, +274},{134,0,2008},{134,0,1794},{4,0,703},{135,0,207},{4,10,472},{140,0,285},{132 +,0,571},{5,0,873},{5,0,960},{8,0,823},{8,11,577},{137,0,881},{7,0,617},{10,0,498 +},{11,0,501},{12,0,16},{140,0,150},{138,10,747},{132,0,431},{133,10,155},{7,10, +163},{8,10,319},{9,10,402},{10,10,24},{10,10,681},{11,0,283},{11,0,567},{11,10, +200},{12,10,253},{12,10,410},{142,10,219},{4,11,413},{5,11,677},{8,11,432},{140, +11,280},{5,10,475},{7,10,1780},{9,0,401},{11,10,297},{11,10,558},{14,10,322},{ +147,10,76},{6,0,781},{9,0,134},{10,0,2},{10,0,27},{10,0,333},{11,0,722},{143,0,1 +},{5,0,33},{6,0,470},{139,0,424},{135,0,2006},{7,10,1956},{140,0,783},{136,0,274 +},{135,0,1882},{132,0,794},{135,0,1848},{5,10,944},{134,10,1769},{6,0,47},{7,0, +90},{7,0,664},{7,0,830},{7,0,1380},{7,0,2025},{8,0,448},{136,0,828},{132,10,144} +,{134,0,1199},{4,11,395},{139,11,762},{135,11,1504},{9,0,417},{137,0,493},{9,11, +174},{10,11,164},{11,11,440},{11,11,841},{143,11,98},{134,11,426},{139,11,1002}, +{134,0,295},{134,0,816},{6,10,247},{137,10,555},{133,0,1019},{4,0,620},{5,11,476 +},{10,10,280},{138,10,797},{139,0,464},{5,11,76},{6,11,458},{6,11,497},{7,11,764 +},{7,11,868},{9,11,658},{10,11,594},{11,11,173},{11,11,566},{12,11,20},{12,11, +338},{141,11,200},{134,0,208},{4,11,526},{7,11,1029},{135,11,1054},{132,11,636}, +{6,11,233},{7,11,660},{7,11,1124},{17,11,31},{19,11,22},{151,11,14},{5,10,428},{ +138,0,442},{10,0,930},{140,0,778},{6,0,68},{7,0,448},{7,0,1629},{7,0,1769},{7,0, +1813},{7,10,1717},{8,0,442},{8,0,516},{9,0,710},{10,0,282},{10,0,722},{138,10, +546},{134,0,1128},{11,0,844},{12,0,104},{140,0,625},{4,11,432},{135,11,824},{138 +,10,189},{133,0,787},{133,10,99},{4,11,279},{7,11,301},{137,11,362},{4,10,397},{ +8,0,491},{136,10,555},{4,11,178},{133,11,399},{134,0,711},{144,0,9},{4,0,403},{5 +,0,441},{7,0,450},{10,0,840},{11,0,101},{12,0,193},{141,0,430},{135,11,1246},{12 +,10,398},{20,10,39},{21,10,11},{150,10,41},{4,10,485},{7,10,353},{135,10,1523},{ +6,10,366},{7,10,1384},{7,10,1601},{135,11,1912},{7,0,396},{7,11,396},{138,0,160} +,{137,10,282},{134,11,1692},{4,10,157},{5,10,471},{6,11,202},{10,11,448},{11,11, +208},{12,11,360},{17,11,117},{17,11,118},{18,11,27},{148,11,67},{133,0,679},{137 +,0,326},{136,10,116},{7,11,872},{10,11,516},{139,11,167},{132,11,224},{5,11,546} +,{7,11,35},{8,11,11},{8,11,12},{9,11,315},{9,11,533},{10,11,802},{11,11,166},{12 +,11,525},{142,11,243},{7,0,1128},{135,11,1920},{5,11,241},{8,11,242},{9,11,451}, +{10,11,667},{11,11,598},{140,11,429},{5,10,160},{6,0,737},{7,10,363},{7,10,589}, +{10,10,170},{141,10,55},{135,0,1796},{142,11,254},{4,0,574},{7,0,350},{7,0,1024} +,{8,0,338},{9,0,677},{138,0,808},{134,0,1096},{137,11,516},{4,10,108},{4,11,366} +,{7,0,405},{10,0,491},{139,10,498},{11,11,337},{142,11,303},{134,11,1736},{7,0, +1081},{140,11,364},{7,10,1005},{140,10,609},{4,10,895},{5,10,772},{135,0,1676},{ +135,0,2037},{6,0,1207},{11,11,916},{142,11,419},{14,11,140},{148,11,41},{6,11, +331},{136,11,623},{4,10,926},{5,10,983},{9,0,944},{9,0,969},{9,0,1022},{12,0,913 +},{12,0,936},{15,0,177},{143,0,193},{5,0,354},{135,11,506},{8,0,598},{9,0,664},{ +138,0,441},{4,11,640},{133,11,513},{137,0,297},{132,10,538},{6,10,294},{7,10, +1267},{136,10,624},{7,0,1772},{7,11,1888},{8,11,289},{11,11,45},{12,11,278},{140 +,11,537},{135,10,1325},{138,0,751},{141,0,37},{134,0,1828},{132,10,757},{132,11, +394},{6,0,257},{135,0,1522},{4,0,582},{7,11,1931},{137,0,191},{7,11,574},{7,11, +1719},{137,11,145},{132,11,658},{4,11,369},{138,0,790},{9,11,781},{10,11,144},{ +11,11,385},{13,11,161},{13,11,228},{13,11,268},{148,11,107},{8,0,469},{8,11,374} +,{138,0,47},{6,0,306},{7,0,1140},{7,0,1340},{8,0,133},{138,0,449},{139,0,1011},{ +7,10,1875},{139,10,124},{4,11,344},{6,11,498},{139,11,323},{137,0,299},{132,0, +837},{133,11,906},{5,0,329},{8,0,260},{138,0,10},{134,0,1320},{4,0,657},{146,0, +158},{135,0,1191},{152,0,7},{6,0,1939},{8,0,974},{138,0,996},{135,0,1665},{11,11 +,126},{139,11,287},{143,0,8},{14,11,149},{14,11,399},{143,11,57},{5,0,66},{7,0, +1896},{136,0,288},{5,10,150},{7,0,175},{8,10,603},{9,10,593},{9,10,634},{10,0, +494},{10,10,173},{11,10,462},{11,10,515},{13,10,216},{13,10,288},{142,10,400},{ +134,0,1643},{136,11,21},{4,0,21},{5,0,91},{5,0,648},{5,0,750},{5,0,781},{6,0,54} +,{6,0,112},{6,0,402},{6,0,1732},{7,0,315},{7,0,749},{7,0,1427},{7,0,1900},{9,0, +78},{9,0,508},{10,0,611},{10,0,811},{11,0,510},{11,0,728},{13,0,36},{14,0,39},{ +16,0,83},{17,0,124},{148,0,30},{4,0,668},{136,0,570},{10,0,322},{10,0,719},{139, +0,407},{135,11,1381},{136,11,193},{12,10,108},{141,10,291},{132,11,616},{136,11, +692},{8,0,125},{8,0,369},{8,0,524},{10,0,486},{11,0,13},{11,0,381},{11,0,736},{ +11,0,766},{11,0,845},{13,0,114},{13,0,292},{142,0,47},{134,0,1247},{6,0,1684},{6 +,0,1731},{7,0,356},{8,0,54},{8,0,221},{9,0,225},{9,0,356},{10,0,77},{10,0,446},{ +10,0,731},{12,0,404},{141,0,491},{135,10,1777},{4,10,493},{4,11,305},{144,10,55} +,{4,0,951},{6,0,1809},{6,0,1849},{8,0,846},{8,0,866},{8,0,899},{10,0,896},{12,0, +694},{142,0,468},{5,11,214},{7,11,603},{8,11,611},{9,11,686},{10,11,88},{11,11, +459},{11,11,496},{12,11,463},{12,11,590},{13,11,0},{142,11,214},{132,0,411},{4,0 +,80},{133,0,44},{140,11,74},{143,0,31},{6,10,568},{7,0,669},{7,10,1804},{8,10, +362},{8,10,410},{8,10,830},{9,10,514},{11,10,649},{142,10,157},{6,11,1703},{135, +0,673},{132,10,625},{134,0,1303},{5,0,299},{135,0,1083},{138,0,704},{6,0,275},{6 +,10,158},{7,0,408},{7,10,129},{7,10,181},{8,10,276},{8,10,377},{10,10,523},{11, +10,816},{12,10,455},{13,10,303},{142,10,135},{4,0,219},{7,0,367},{7,0,1713},{7,0 +,1761},{9,0,86},{9,0,537},{10,0,165},{12,0,219},{140,0,561},{4,10,1},{4,11,737}, +{6,11,317},{7,10,1143},{7,10,1463},{8,0,216},{9,10,207},{9,10,390},{9,10,467},{ +10,11,98},{11,10,836},{11,11,294},{12,11,60},{12,11,437},{13,11,64},{13,11,380}, +{142,11,430},{6,11,1758},{8,11,520},{9,11,345},{9,11,403},{142,11,350},{5,11,47} +,{10,11,242},{138,11,579},{5,11,139},{7,11,1168},{138,11,539},{135,0,1319},{4,10 +,295},{4,10,723},{5,10,895},{7,10,1031},{8,10,199},{8,10,340},{9,10,153},{9,10, +215},{10,10,21},{10,10,59},{10,10,80},{10,10,224},{10,10,838},{11,10,229},{11,10 +,652},{12,10,192},{13,10,146},{142,10,91},{140,0,428},{137,10,51},{133,0,514},{5 +,10,309},{140,10,211},{5,10,125},{6,0,1010},{8,10,77},{138,10,15},{4,0,55},{5,0, +301},{6,0,571},{142,0,49},{146,0,102},{136,11,370},{4,11,107},{7,11,613},{8,11, +358},{8,11,439},{8,11,504},{9,11,501},{10,11,383},{139,11,477},{132,11,229},{133 +,0,364},{133,10,439},{4,11,903},{135,11,1816},{11,0,379},{140,10,76},{4,0,76},{4 +,0,971},{7,0,1550},{9,0,306},{9,0,430},{9,0,663},{10,0,683},{10,0,921},{11,0,427 +},{11,0,753},{12,0,334},{12,0,442},{14,0,258},{14,0,366},{143,0,131},{137,0,52}, +{4,11,47},{6,11,373},{7,11,452},{7,11,543},{7,11,1714},{7,11,1856},{9,11,6},{11, +11,257},{139,11,391},{4,10,8},{7,10,1152},{7,10,1153},{7,10,1715},{9,10,374},{10 +,10,478},{139,10,648},{4,11,785},{133,11,368},{135,10,1099},{135,11,860},{5,11, +980},{134,11,1754},{134,0,1258},{6,0,1058},{6,0,1359},{7,11,536},{7,11,1331},{ +136,11,143},{4,0,656},{135,0,779},{136,10,87},{5,11,19},{6,11,533},{146,11,126}, +{7,0,144},{138,10,438},{5,11,395},{5,11,951},{134,11,1776},{135,0,1373},{7,0,554 +},{7,0,605},{141,0,10},{4,10,69},{5,10,122},{9,10,656},{138,10,464},{5,10,849},{ +134,10,1633},{5,0,838},{5,0,841},{134,0,1649},{133,0,1012},{139,10,499},{7,10, +476},{7,10,1592},{138,10,87},{6,0,251},{7,0,365},{7,0,1357},{7,0,1497},{8,0,154} +,{141,0,281},{132,11,441},{132,11,695},{7,11,497},{9,11,387},{147,11,81},{133,0, +340},{14,10,283},{142,11,283},{134,0,810},{135,11,1894},{139,0,495},{5,11,284},{ +6,11,49},{6,11,350},{7,11,1},{7,11,377},{7,11,1693},{8,11,18},{8,11,678},{9,11, +161},{9,11,585},{9,11,671},{9,11,839},{11,11,912},{141,11,427},{5,10,859},{7,10, +1160},{8,10,107},{9,10,291},{9,10,439},{10,10,663},{11,10,609},{140,10,197},{8,0 +,261},{9,0,144},{9,0,466},{10,0,370},{12,0,470},{13,0,144},{142,0,348},{137,0, +897},{6,0,248},{9,0,546},{10,0,535},{11,0,681},{141,0,135},{4,0,358},{135,0,1496 +},{134,0,567},{136,0,445},{4,10,117},{6,10,372},{7,10,1905},{142,10,323},{4,10, +722},{139,10,471},{6,0,697},{134,0,996},{7,11,2007},{9,11,101},{9,11,450},{10,11 +,66},{10,11,842},{11,11,536},{140,11,587},{132,0,577},{134,0,1336},{9,10,5},{12, +10,216},{12,10,294},{12,10,298},{12,10,400},{12,10,518},{13,10,229},{143,10,139} +,{6,0,174},{138,0,917},{134,10,1774},{5,10,12},{7,10,375},{9,10,88},{9,10,438},{ +11,10,270},{139,11,62},{134,11,1766},{6,11,0},{7,10,816},{7,10,1241},{7,11,84},{ +9,10,283},{9,10,520},{10,10,213},{10,10,307},{10,10,463},{10,10,671},{10,10,746} +,{11,10,401},{11,10,794},{11,11,895},{12,10,517},{17,11,11},{18,10,107},{147,10, +115},{5,0,878},{133,0,972},{6,11,1665},{7,11,256},{7,11,1388},{138,11,499},{4,10 +,258},{136,10,639},{4,11,22},{5,11,10},{6,10,22},{7,10,903},{7,10,1963},{7,11, +848},{8,11,97},{138,10,577},{5,10,681},{136,10,782},{133,11,481},{132,0,351},{4, +10,664},{5,10,804},{139,10,1013},{6,11,134},{7,11,437},{7,11,959},{9,11,37},{14, +11,285},{14,11,371},{144,11,60},{7,11,486},{8,11,155},{11,11,93},{140,11,164},{ +132,0,286},{7,0,438},{7,0,627},{7,0,1516},{8,0,40},{9,0,56},{9,0,294},{10,0,30}, +{11,0,969},{11,0,995},{146,0,148},{5,11,591},{135,11,337},{134,0,1950},{133,10, +32},{138,11,500},{5,11,380},{5,11,650},{136,11,310},{4,11,364},{7,11,1156},{7,11 +,1187},{137,11,409},{4,0,738},{134,11,482},{4,11,781},{6,11,487},{7,11,926},{8, +11,263},{139,11,500},{135,11,418},{4,10,289},{6,0,2047},{7,10,629},{7,10,1698},{ +7,10,1711},{10,0,969},{140,10,215},{6,10,450},{136,10,109},{134,0,818},{136,10, +705},{133,0,866},{4,11,94},{135,11,1265},{132,11,417},{134,0,1467},{135,10,1238} +,{4,0,972},{6,0,1851},{134,0,1857},{134,0,355},{133,0,116},{132,0,457},{135,11, +1411},{4,11,408},{4,11,741},{135,11,500},{134,10,26},{142,11,137},{5,0,527},{6,0 +,189},{7,0,859},{136,0,267},{11,0,104},{11,0,554},{15,0,60},{143,0,125},{134,0, +1613},{4,10,414},{5,10,467},{9,10,654},{10,10,451},{12,10,59},{141,10,375},{135, +10,17},{134,0,116},{135,11,541},{135,10,955},{6,11,73},{135,11,177},{133,11,576} +,{134,0,886},{133,0,487},{4,0,86},{5,0,667},{5,0,753},{6,0,316},{6,0,455},{135,0 +,946},{142,11,231},{150,0,45},{134,0,863},{134,0,1953},{6,10,280},{10,10,502},{ +11,10,344},{140,10,38},{4,0,79},{7,0,1773},{10,0,450},{11,0,589},{13,0,332},{13, +0,493},{14,0,183},{14,0,334},{14,0,362},{14,0,368},{14,0,376},{14,0,379},{19,0, +90},{19,0,103},{19,0,127},{148,0,90},{5,10,45},{7,10,1161},{11,10,448},{11,10, +880},{13,10,139},{13,10,407},{15,10,16},{17,10,95},{18,10,66},{18,10,88},{18,10, +123},{149,10,7},{136,10,777},{4,10,410},{135,10,521},{135,10,1778},{135,11,538}, +{142,0,381},{133,11,413},{134,0,1142},{6,0,1189},{136,11,495},{5,0,663},{6,0, +1962},{134,0,2003},{7,11,54},{8,11,312},{10,11,191},{10,11,614},{140,11,567},{ +132,10,436},{133,0,846},{7,10,1587},{7,10,1707},{10,0,528},{139,0,504},{5,0,378} +,{8,0,465},{9,0,286},{10,0,185},{10,0,562},{10,0,635},{11,0,31},{11,0,393},{13,0 +,312},{18,0,65},{18,0,96},{147,0,89},{6,11,468},{7,0,899},{7,11,567},{7,11,1478} +,{8,11,530},{14,0,325},{142,11,290},{7,0,1880},{9,0,680},{139,0,798},{134,0,1770 +},{132,0,648},{150,11,35},{5,0,945},{6,0,1656},{6,0,1787},{7,0,167},{8,0,824},{9 +,0,391},{10,0,375},{139,0,185},{6,11,484},{135,11,822},{134,0,2046},{7,0,1645},{ +8,0,352},{137,0,249},{132,0,152},{6,0,611},{135,0,1733},{6,11,1724},{135,11,2022 +},{133,0,1006},{141,11,96},{5,0,420},{135,0,1449},{146,11,149},{135,0,832},{135, +10,663},{133,0,351},{5,0,40},{7,0,598},{7,0,1638},{8,0,78},{9,0,166},{9,0,640},{ +9,0,685},{9,0,773},{11,0,215},{13,0,65},{14,0,172},{14,0,317},{145,0,6},{8,0,60} +,{9,0,343},{139,0,769},{134,0,1354},{132,0,724},{137,0,745},{132,11,474},{7,0, +1951},{8,0,765},{8,0,772},{140,0,671},{7,0,108},{8,0,219},{8,0,388},{9,0,775},{ +11,0,275},{140,0,464},{137,0,639},{135,10,503},{133,11,366},{5,0,15},{5,11,305}, +{6,0,56},{7,0,1758},{8,0,500},{9,0,730},{9,11,560},{11,0,331},{13,0,150},{13,11, +208},{142,0,282},{4,10,113},{5,10,163},{5,10,735},{7,10,1009},{9,10,9},{9,10,771 +},{12,10,90},{13,10,138},{13,10,410},{143,10,128},{4,10,324},{138,10,104},{135, +11,466},{142,11,27},{134,0,1886},{4,11,480},{5,0,205},{6,0,438},{6,11,167},{6,11 +,302},{6,11,1642},{7,11,130},{7,11,656},{7,11,837},{7,11,1547},{7,11,1657},{8,11 +,429},{9,0,711},{9,11,228},{10,11,643},{13,11,289},{13,11,343},{147,11,101},{134 +,0,865},{6,0,2025},{136,0,965},{7,11,278},{10,11,739},{11,11,708},{141,11,348},{ +133,0,534},{135,11,1922},{137,0,691},{4,10,935},{133,10,823},{6,0,443},{9,0,237} +,{9,0,571},{9,0,695},{10,0,139},{11,0,715},{12,0,417},{141,0,421},{5,10,269},{7, +10,434},{7,10,891},{8,10,339},{9,10,702},{11,10,594},{11,10,718},{145,10,100},{6 +,0,1555},{7,0,878},{9,10,485},{141,10,264},{134,10,1713},{7,10,1810},{11,10,866} +,{12,10,103},{141,10,495},{135,10,900},{6,0,1410},{9,11,316},{139,11,256},{4,0, +995},{135,0,1033},{132,0,578},{10,0,881},{12,0,740},{12,0,743},{140,0,759},{132, +0,822},{133,0,923},{142,10,143},{135,11,1696},{6,11,363},{7,11,1955},{136,11,725 +},{132,0,924},{133,0,665},{135,10,2029},{135,0,1901},{4,0,265},{6,0,1092},{6,0, +1417},{7,0,807},{135,0,950},{5,0,93},{12,0,267},{141,0,498},{135,0,1451},{5,11, +813},{135,11,2046},{5,10,625},{135,10,1617},{135,0,747},{6,0,788},{137,0,828},{5 +,11,712},{7,0,184},{7,11,1855},{8,10,425},{8,10,693},{9,10,720},{10,10,380},{10, +10,638},{11,0,307},{11,0,400},{11,10,473},{11,11,17},{12,10,61},{13,11,321},{15, +0,130},{144,11,67},{135,0,198},{6,11,320},{7,11,781},{7,11,1921},{9,11,55},{10, +11,186},{10,11,273},{10,11,664},{10,11,801},{11,11,996},{11,11,997},{13,11,157}, +{142,11,170},{136,11,271},{135,0,994},{7,11,103},{7,11,863},{11,11,184},{14,11, +299},{145,11,62},{11,10,551},{142,10,159},{5,0,233},{5,0,320},{6,0,140},{8,0,295 +},{8,0,615},{136,11,615},{133,0,978},{4,0,905},{6,0,1701},{137,0,843},{132,10, +168},{4,0,974},{8,0,850},{12,0,709},{12,0,768},{140,0,786},{135,10,91},{152,0,6} +,{138,10,532},{135,10,1884},{132,0,509},{6,0,1307},{135,0,273},{5,11,77},{7,11, +1455},{10,11,843},{19,11,73},{150,11,5},{132,11,458},{135,11,1420},{6,11,109},{ +138,11,382},{6,0,201},{6,11,330},{7,10,70},{7,11,1084},{10,10,240},{11,11,142},{ +147,10,93},{7,0,1041},{140,11,328},{133,11,354},{134,0,1040},{133,0,693},{134,0, +774},{139,0,234},{132,0,336},{7,0,1399},{139,10,392},{20,0,22},{148,11,22},{5,0, +802},{7,0,2021},{136,0,805},{5,0,167},{5,0,899},{6,0,410},{137,0,777},{137,0,789 +},{134,0,1705},{7,10,655},{135,10,1844},{4,10,145},{6,10,176},{7,10,395},{137,10 +,562},{132,10,501},{135,0,10},{5,0,11},{6,0,117},{6,0,485},{6,10,509},{7,0,1133} +,{9,0,582},{9,0,594},{10,0,82},{11,0,21},{11,0,818},{12,0,535},{13,0,86},{20,0, +91},{151,0,13},{4,0,264},{7,0,1067},{8,0,204},{8,0,385},{139,0,953},{139,11,737} +,{138,0,56},{134,0,1917},{133,0,470},{10,11,657},{14,11,297},{142,11,361},{135, +11,412},{7,0,1198},{7,11,1198},{8,11,556},{14,11,123},{14,11,192},{143,11,27},{7 +,11,1985},{14,11,146},{15,11,42},{16,11,23},{17,11,86},{146,11,17},{8,11,122},{ +139,0,1015},{4,10,114},{9,10,492},{13,10,462},{142,10,215},{4,10,77},{5,10,361}, +{6,10,139},{6,10,401},{6,10,404},{7,10,413},{7,10,715},{7,10,1716},{11,10,279},{ +12,10,179},{12,10,258},{13,10,244},{142,10,358},{134,10,1717},{7,10,1061},{8,10, +82},{11,10,250},{12,10,420},{141,10,184},{133,0,715},{135,10,724},{9,0,919},{9,0 +,922},{9,0,927},{9,0,933},{9,0,962},{9,0,1000},{9,0,1002},{9,0,1021},{12,0,890}, +{12,0,907},{12,0,930},{15,0,207},{15,0,228},{15,0,238},{149,0,61},{8,0,794},{9,0 +,400},{10,0,298},{142,0,228},{5,11,430},{5,11,932},{6,11,131},{7,11,417},{9,11, +522},{11,11,314},{141,11,390},{132,0,867},{4,11,507},{136,0,724},{137,11,261},{4 +,11,343},{133,11,511},{6,0,190},{7,0,768},{135,0,1170},{6,10,513},{135,10,1052}, +{7,11,455},{138,11,591},{134,0,1066},{137,10,899},{14,0,67},{147,0,60},{4,0,948} +,{18,0,174},{146,0,176},{135,0,1023},{7,10,1417},{12,10,382},{17,10,48},{152,10, +12},{134,11,575},{132,0,764},{6,10,545},{7,10,565},{7,10,1669},{10,10,114},{11, +10,642},{140,10,618},{6,0,137},{9,0,75},{9,0,253},{10,0,194},{138,0,444},{4,0, +756},{133,10,5},{7,10,192},{136,0,1008},{132,0,842},{8,10,763},{11,0,643},{140,0 +,115},{139,0,67},{133,10,759},{4,0,821},{5,0,760},{7,0,542},{7,11,580},{8,0,135} +,{136,0,496},{7,10,370},{7,10,1007},{7,10,1177},{135,10,1565},{135,10,1237},{140 +,0,736},{7,0,319},{7,0,355},{7,0,763},{10,0,389},{145,0,43},{8,11,333},{138,11, +182},{4,10,87},{5,10,250},{141,10,298},{138,0,786},{134,0,2044},{8,11,330},{140, +11,477},{135,11,1338},{132,11,125},{134,0,1030},{134,0,1083},{132,11,721},{135, +10,814},{7,11,776},{8,11,145},{147,11,56},{134,0,1226},{4,10,57},{7,10,1195},{7, +10,1438},{7,10,1548},{7,10,1835},{7,10,1904},{9,10,757},{10,10,604},{139,10,519} +,{7,11,792},{8,11,147},{10,11,821},{139,11,1021},{137,11,797},{4,0,58},{5,0,286} +,{6,0,319},{7,0,402},{7,0,1254},{7,0,1903},{8,0,356},{140,0,408},{4,0,389},{4,0, +815},{9,0,181},{9,0,255},{10,0,8},{10,0,29},{10,0,816},{11,0,311},{11,0,561},{12 +,0,67},{141,0,181},{7,11,1472},{135,11,1554},{7,11,1071},{7,11,1541},{7,11,1767} +,{7,11,1806},{7,11,1999},{9,11,248},{10,11,400},{11,11,162},{11,11,178},{11,11, +242},{12,11,605},{15,11,26},{144,11,44},{5,11,168},{5,11,930},{8,11,74},{9,11, +623},{12,11,500},{12,11,579},{13,11,41},{143,11,93},{6,11,220},{7,11,1101},{141, +11,105},{4,10,209},{5,0,474},{7,0,507},{7,10,902},{135,11,507},{132,0,427},{6,0, +413},{7,10,335},{7,10,1437},{7,10,1668},{8,10,553},{8,10,652},{8,10,656},{9,10, +558},{11,10,743},{149,10,18},{132,0,730},{6,11,19},{7,11,1413},{139,11,428},{133 +,0,373},{132,10,559},{7,11,96},{8,11,401},{137,11,896},{5,10,1017},{7,0,799},{7, +0,1972},{138,10,511},{135,0,1793},{7,11,1961},{7,11,1965},{8,11,702},{136,11,750 +},{8,11,150},{8,11,737},{140,11,366},{132,0,322},{133,10,709},{8,11,800},{9,11, +148},{9,11,872},{9,11,890},{11,11,309},{11,11,1001},{13,11,267},{141,11,323},{ +134,10,1745},{7,0,290},{136,10,206},{7,0,1651},{145,0,89},{139,0,2},{132,0,672}, +{6,0,1860},{8,0,905},{10,0,844},{10,0,846},{10,0,858},{12,0,699},{12,0,746},{140 +,0,772},{135,11,424},{133,11,547},{133,0,737},{5,11,490},{6,11,615},{6,11,620},{ +135,11,683},{6,0,746},{134,0,1612},{132,10,776},{9,11,385},{149,11,17},{133,0, +145},{135,10,1272},{7,0,884},{140,0,124},{4,0,387},{135,0,1288},{5,11,133},{136, +10,406},{136,11,187},{6,0,679},{8,11,8},{138,11,0},{135,0,550},{135,11,798},{136 +,11,685},{7,11,1086},{145,11,46},{8,10,175},{10,10,168},{138,10,573},{135,0,1305 +},{4,0,576},{135,0,1263},{6,0,686},{134,0,1563},{134,0,607},{5,0,919},{134,0, +1673},{148,0,37},{8,11,774},{10,11,670},{140,11,51},{133,10,784},{139,10,882},{4 +,0,82},{5,0,333},{5,0,904},{6,0,207},{7,0,325},{7,0,1726},{8,0,101},{10,0,778},{ +139,0,220},{135,11,371},{132,0,958},{133,0,903},{4,11,127},{5,11,350},{6,11,356} +,{8,11,426},{9,11,572},{10,11,247},{139,11,312},{140,0,147},{6,11,59},{7,11,885} +,{9,11,603},{141,11,397},{9,10,14},{9,10,441},{10,0,367},{139,10,9},{11,10,966}, +{12,10,287},{13,10,342},{13,10,402},{15,10,110},{143,10,163},{134,0,690},{132,0, +705},{7,10,1428},{7,10,1640},{7,10,1867},{9,0,651},{9,10,169},{9,10,182},{9,10, +367},{9,10,478},{9,10,506},{9,10,551},{9,10,557},{9,10,648},{9,10,697},{9,10,705 +},{9,10,725},{9,10,787},{9,10,794},{10,10,198},{10,10,214},{10,10,267},{10,10, +275},{10,10,456},{10,10,551},{10,10,561},{10,10,613},{10,10,627},{10,10,668},{10 +,10,675},{10,10,691},{10,10,695},{10,10,707},{10,10,715},{11,0,971},{11,10,183}, +{11,10,201},{11,10,262},{11,10,352},{11,10,439},{11,10,493},{11,10,572},{11,10, +591},{11,10,608},{11,10,611},{11,10,646},{11,10,674},{11,10,711},{11,10,751},{11 +,10,761},{11,10,776},{11,10,785},{11,10,850},{11,10,853},{11,10,862},{11,10,865} +,{11,10,868},{11,10,875},{11,10,898},{11,10,902},{11,10,903},{11,10,910},{11,10, +932},{11,10,942},{11,10,957},{11,10,967},{11,10,972},{12,10,148},{12,10,195},{12 +,10,220},{12,10,237},{12,10,318},{12,10,339},{12,10,393},{12,10,445},{12,10,450} +,{12,10,474},{12,10,505},{12,10,509},{12,10,533},{12,10,591},{12,10,594},{12,10, +597},{12,10,621},{12,10,633},{12,10,642},{13,0,273},{13,10,59},{13,10,60},{13,10 +,145},{13,10,239},{13,10,250},{13,10,329},{13,10,344},{13,10,365},{13,10,372},{ +13,10,387},{13,10,403},{13,10,414},{13,10,456},{13,10,470},{13,10,478},{13,10, +483},{13,10,489},{14,10,55},{14,10,57},{14,10,81},{14,10,90},{14,10,148},{14,10, +239},{14,10,266},{14,10,321},{14,10,326},{14,10,327},{14,10,330},{14,10,347},{14 +,10,355},{14,10,401},{14,10,404},{14,10,411},{14,10,414},{14,10,416},{14,10,420} +,{15,10,61},{15,10,74},{15,10,87},{15,10,88},{15,10,94},{15,10,96},{15,10,116},{ +15,10,149},{15,10,154},{16,10,50},{16,10,63},{16,10,73},{17,10,2},{17,10,66},{17 +,10,92},{17,10,103},{17,10,112},{17,10,120},{18,10,50},{18,10,54},{18,10,82},{18 +,10,86},{18,10,90},{18,10,111},{18,10,115},{18,10,156},{19,10,40},{19,10,79},{20 +,10,78},{149,10,22},{5,10,161},{7,0,887},{135,10,839},{142,11,98},{134,0,90},{ +138,11,356},{135,11,441},{6,11,111},{7,11,4},{8,11,163},{8,11,776},{138,11,566}, +{134,0,908},{134,0,1261},{7,0,813},{12,0,497},{141,0,56},{134,0,1235},{135,0,429 +},{135,11,1994},{138,0,904},{6,0,125},{7,0,1277},{137,0,772},{151,0,12},{4,0,841 +},{5,0,386},{133,11,386},{5,11,297},{135,11,1038},{6,0,860},{6,0,1069},{135,11, +309},{136,0,946},{135,10,1814},{141,11,418},{136,11,363},{10,0,768},{139,0,787}, +{22,11,30},{150,11,33},{6,0,160},{7,0,1106},{9,0,770},{11,0,112},{140,0,413},{11 +,11,216},{139,11,340},{136,10,139},{135,11,1390},{135,11,808},{132,11,280},{7,10 +,643},{8,10,236},{12,0,271},{145,0,109},{140,11,54},{4,11,421},{133,11,548},{11, +0,719},{12,0,36},{141,0,337},{7,0,581},{9,0,644},{137,0,699},{11,11,511},{13,11, +394},{14,11,298},{14,11,318},{146,11,103},{7,0,304},{9,0,646},{9,0,862},{11,0, +696},{12,0,208},{15,0,79},{147,0,108},{4,0,631},{7,0,1126},{135,0,1536},{135,11, +1527},{8,0,880},{10,0,869},{138,0,913},{5,10,54},{6,11,254},{7,0,1513},{9,11,109 +},{138,11,103},{135,0,981},{133,11,729},{132,10,744},{132,0,434},{134,0,550},{6, +11,1630},{7,0,930},{10,0,476},{10,10,402},{13,0,452},{18,10,55},{147,0,104},{5,0 +,553},{138,0,824},{136,0,452},{8,0,151},{137,10,624},{132,10,572},{132,0,772},{ +133,11,671},{133,0,292},{138,0,135},{132,11,889},{140,11,207},{6,10,43},{7,10,38 +},{8,10,248},{9,0,504},{138,10,513},{6,0,1089},{135,11,1910},{4,11,627},{133,11, +775},{135,0,783},{133,10,766},{133,10,363},{7,0,387},{135,11,387},{7,0,393},{7, +11,202},{10,0,603},{11,0,206},{11,11,362},{11,11,948},{140,11,388},{6,11,507},{7 +,11,451},{8,11,389},{12,11,490},{13,11,16},{13,11,215},{13,11,351},{18,11,132},{ +147,11,125},{4,0,912},{7,11,841},{137,0,232},{6,10,258},{140,10,409},{5,10,249}, +{148,10,82},{136,11,566},{6,0,977},{135,11,1214},{7,0,1973},{136,0,716},{135,0, +98},{133,0,733},{5,11,912},{134,11,1695},{5,10,393},{6,10,378},{7,10,1981},{9,10 +,32},{9,10,591},{10,10,685},{10,10,741},{142,10,382},{133,10,788},{7,10,1968},{ +10,0,19},{11,0,911},{141,10,509},{5,0,668},{5,11,236},{6,11,572},{8,11,492},{11, +11,618},{144,11,56},{135,11,1789},{4,0,360},{5,0,635},{5,0,700},{5,10,58},{5,10, +171},{5,10,683},{6,10,291},{6,10,566},{7,10,1650},{11,10,523},{12,10,273},{12,10 +,303},{15,10,39},{143,10,111},{133,0,901},{134,10,589},{5,11,190},{136,11,318},{ +140,0,656},{7,0,726},{152,0,9},{4,10,917},{133,10,1005},{135,10,1598},{134,11, +491},{4,10,919},{133,11,434},{137,0,72},{6,0,1269},{6,0,1566},{134,0,1621},{4,10 +,255},{5,10,302},{6,10,132},{7,10,128},{7,10,283},{7,10,1299},{9,0,463},{10,0, +595},{10,10,52},{10,10,514},{11,10,925},{13,10,92},{142,10,309},{135,0,1454},{ +134,0,1287},{9,10,173},{11,0,600},{141,0,245},{136,0,989},{7,0,164},{7,0,1571},{ +9,0,107},{140,0,225},{6,0,1061},{141,10,442},{4,0,27},{5,0,484},{5,0,510},{6,0, +434},{7,0,1000},{7,0,1098},{136,0,2},{7,11,85},{7,11,247},{8,11,585},{10,11,163} +,{138,11,316},{11,11,103},{142,11,0},{134,0,1127},{4,0,460},{134,0,852},{134,10, +210},{4,0,932},{133,0,891},{6,0,588},{147,11,83},{4,10,284},{6,10,223},{136,0, +625},{134,0,76},{8,0,92},{137,0,221},{4,11,124},{10,11,457},{11,11,121},{11,11, +169},{11,11,422},{11,11,870},{12,11,214},{13,11,389},{14,11,187},{143,11,77},{9, +11,618},{138,11,482},{4,10,218},{7,10,526},{143,10,137},{4,10,270},{5,10,192},{6 +,10,332},{7,10,1322},{13,0,9},{14,0,104},{142,0,311},{140,10,661},{135,11,1193}, +{6,11,107},{7,11,638},{7,11,1632},{137,11,396},{132,0,763},{4,0,622},{5,11,370}, +{134,11,1756},{133,0,253},{135,0,546},{5,11,204},{9,0,73},{10,0,110},{14,0,185}, +{145,0,119},{7,0,624},{7,0,916},{10,0,256},{139,0,87},{7,10,379},{8,10,481},{137 +,10,377},{5,0,212},{5,11,970},{6,11,1706},{12,0,35},{141,0,382},{5,10,1003},{6, +10,149},{137,0,746},{8,10,262},{9,10,627},{10,0,150},{11,0,849},{11,10,214},{11, +10,404},{11,10,457},{11,10,780},{11,10,913},{13,0,330},{13,10,401},{142,10,200}, +{134,0,1466},{135,11,3},{4,11,35},{5,11,121},{5,11,483},{5,11,685},{6,0,1299},{6 +,11,489},{7,11,1204},{136,11,394},{135,10,742},{4,10,142},{136,10,304},{4,11,921 +},{133,11,1007},{134,0,1518},{6,0,1229},{135,0,1175},{133,0,816},{4,10,471},{4, +11,712},{5,10,51},{6,10,602},{7,10,925},{8,10,484},{10,10,195},{140,0,159},{134, +11,1629},{5,0,869},{5,0,968},{6,0,1626},{8,0,734},{136,0,784},{4,0,542},{6,0, +1716},{6,0,1727},{7,0,1082},{7,0,1545},{8,0,56},{8,0,118},{8,0,412},{8,0,564},{8 +,10,688},{9,0,888},{9,0,908},{10,0,50},{10,0,423},{11,0,685},{11,0,697},{11,0, +933},{12,0,299},{13,0,126},{13,0,136},{13,0,170},{141,0,190},{132,10,697},{4,0, +232},{9,0,202},{10,0,474},{140,0,433},{136,0,212},{6,0,108},{7,0,1003},{7,0,1181 +},{8,0,111},{136,0,343},{5,10,221},{135,11,1255},{133,11,485},{134,0,1712},{142, +0,216},{4,11,285},{5,0,643},{5,11,317},{6,0,516},{6,11,301},{7,11,7},{8,11,153}, +{10,11,766},{11,11,468},{12,11,467},{141,11,143},{4,0,133},{7,0,711},{7,0,1298}, +{135,0,1585},{134,0,650},{135,11,512},{6,0,99},{7,0,1808},{145,0,57},{6,0,246},{ +6,0,574},{7,0,428},{9,0,793},{10,0,669},{11,0,485},{11,0,840},{12,0,300},{14,0, +250},{145,0,55},{4,10,132},{5,10,69},{135,10,1242},{136,0,1023},{4,10,111},{135, +0,302},{135,0,1871},{132,0,728},{4,10,767},{137,0,252},{6,0,461},{7,0,1590},{7, +10,1416},{7,10,2005},{8,10,131},{8,10,466},{9,10,672},{13,10,252},{148,10,103},{ +6,0,323},{135,0,1564},{7,0,461},{136,0,775},{6,10,44},{136,10,368},{139,0,172},{ +132,0,464},{4,10,570},{133,10,120},{137,11,269},{6,10,227},{135,10,1589},{6,11, +1719},{6,11,1735},{7,11,2016},{7,11,2020},{8,11,837},{137,11,852},{7,0,727},{146 +,0,73},{132,0,1023},{135,11,852},{135,10,1529},{136,0,577},{138,11,568},{134,0, +1037},{8,11,67},{138,11,419},{4,0,413},{5,0,677},{8,0,432},{140,0,280},{6,10, +1667},{7,10,2036},{7,11,967},{10,0,600},{141,11,11},{6,10,511},{140,10,132},{5, +10,568},{6,0,799},{6,10,138},{135,10,1293},{4,10,565},{8,0,159},{136,10,827},{7, +0,646},{7,0,1730},{11,0,446},{141,0,178},{4,10,922},{133,10,1023},{135,11,11},{ +132,0,395},{7,10,1002},{139,0,145},{9,0,174},{10,0,164},{11,0,440},{11,0,514},{ +11,0,841},{15,0,98},{149,0,20},{134,0,426},{10,0,608},{139,0,1002},{7,11,320},{8 +,11,51},{12,11,481},{12,11,570},{148,11,106},{4,11,445},{9,0,977},{137,0,983},{ +138,0,250},{139,0,100},{6,0,1982},{136,10,402},{133,11,239},{4,10,716},{141,10, +31},{5,0,476},{7,11,83},{7,11,1990},{8,11,130},{139,11,720},{8,10,691},{136,10, +731},{5,11,123},{6,11,530},{7,11,348},{135,11,1419},{5,0,76},{6,0,458},{6,0,497} +,{7,0,868},{9,0,658},{10,0,594},{11,0,173},{11,0,566},{12,0,20},{12,0,338},{141, +0,200},{9,11,139},{10,11,399},{11,11,469},{12,11,634},{141,11,223},{9,10,840},{ +138,10,803},{133,10,847},{11,11,223},{140,11,168},{132,11,210},{8,0,447},{9,10, +53},{9,10,268},{9,10,901},{10,10,518},{10,10,829},{11,10,188},{13,10,74},{14,10, +46},{15,10,17},{15,10,33},{17,10,40},{18,10,36},{19,10,20},{22,10,1},{152,10,2}, +{4,0,526},{7,0,1029},{135,0,1054},{19,11,59},{150,11,2},{4,0,636},{6,0,1875},{6, +0,1920},{8,10,532},{9,0,999},{12,0,807},{12,0,825},{15,0,179},{15,0,190},{146,0, +182},{6,0,1699},{7,0,660},{7,0,1124},{17,0,31},{19,0,22},{151,0,14},{135,10,681} +,{132,11,430},{140,10,677},{4,10,684},{136,10,384},{132,11,756},{133,11,213},{7, +0,188},{7,10,110},{8,10,290},{8,10,591},{9,10,382},{9,10,649},{11,10,71},{11,10, +155},{11,10,313},{12,10,5},{13,10,325},{142,10,287},{7,10,360},{7,10,425},{9,10, +66},{9,10,278},{138,10,644},{142,11,164},{4,0,279},{7,0,301},{137,0,362},{134,11 +,586},{135,0,1743},{4,0,178},{133,0,399},{4,10,900},{133,10,861},{5,10,254},{7, +10,985},{136,10,73},{133,11,108},{7,10,1959},{136,10,683},{133,11,219},{4,11,193 +},{5,11,916},{7,11,364},{10,11,398},{10,11,726},{11,11,317},{11,11,626},{12,11, +142},{12,11,288},{12,11,678},{13,11,313},{15,11,113},{18,11,114},{21,11,30},{150 +,11,53},{6,11,241},{7,11,907},{8,11,832},{9,11,342},{10,11,729},{11,11,284},{11, +11,445},{11,11,651},{11,11,863},{13,11,398},{146,11,99},{132,0,872},{134,0,831}, +{134,0,1692},{6,0,202},{6,0,1006},{9,0,832},{9,11,734},{10,0,636},{11,0,208},{12 +,0,360},{17,0,118},{18,0,27},{148,0,67},{132,10,725},{7,11,993},{138,11,666},{ +134,0,1954},{134,10,196},{7,0,872},{10,0,516},{139,0,167},{133,10,831},{4,11,562 +},{9,11,254},{139,11,879},{137,0,313},{4,0,224},{132,11,786},{8,10,723},{11,0,24 +},{140,0,170},{5,0,546},{7,0,35},{8,0,11},{8,0,12},{9,0,315},{9,0,533},{10,0,802 +},{11,0,166},{12,0,525},{142,0,243},{7,0,1937},{13,10,80},{13,10,437},{145,10,74 +},{5,0,241},{8,0,242},{9,0,451},{10,0,667},{11,0,598},{140,0,429},{150,0,46},{6, +0,1273},{137,0,830},{5,10,848},{6,10,66},{136,10,764},{6,0,825},{134,0,993},{4,0 +,1006},{4,10,36},{7,10,1387},{10,0,327},{11,10,755},{141,0,271},{134,0,1023},{ +135,0,1580},{4,0,366},{137,0,516},{132,10,887},{6,0,1736},{135,0,1891},{6,11,216 +},{7,11,901},{7,11,1343},{136,11,493},{6,10,165},{138,10,388},{7,11,341},{139,11 +,219},{4,10,719},{135,10,155},{134,0,1935},{132,0,826},{6,0,331},{6,0,1605},{8,0 +,623},{11,0,139},{139,0,171},{135,11,1734},{10,11,115},{11,11,420},{12,11,154},{ +13,11,404},{14,11,346},{15,11,54},{143,11,112},{4,10,353},{6,10,146},{6,10,1789} +,{7,0,288},{7,10,990},{7,10,1348},{9,10,665},{9,10,898},{11,10,893},{142,10,212} +,{6,0,916},{134,0,1592},{4,10,45},{7,0,1888},{135,10,1257},{5,11,1011},{136,11, +701},{139,11,596},{4,11,54},{5,11,666},{7,11,1039},{7,11,1130},{9,11,195},{138, +11,302},{134,0,1471},{134,0,1570},{132,0,394},{140,10,65},{136,10,816},{135,0, +1931},{7,0,574},{135,0,1719},{134,11,467},{132,0,658},{6,11,1669},{9,0,781},{10, +0,144},{11,0,385},{13,0,161},{13,0,228},{13,0,268},{148,0,107},{136,0,374},{135, +0,735},{4,0,344},{6,0,498},{139,0,323},{6,10,559},{6,10,1691},{7,0,586},{135,0, +1063},{137,0,155},{133,0,906},{7,11,122},{9,11,259},{10,11,84},{11,11,470},{12, +11,541},{141,11,379},{134,0,1139},{10,0,108},{139,0,116},{134,10,456},{133,10, +925},{5,11,82},{5,11,131},{7,11,1755},{8,11,31},{9,11,168},{9,11,764},{139,11, +869},{134,11,605},{5,11,278},{137,11,68},{4,11,163},{5,11,201},{5,11,307},{5,11, +310},{6,11,335},{7,11,284},{136,11,165},{135,11,1660},{6,11,33},{135,11,1244},{4 +,0,616},{136,11,483},{4,11,199},{8,0,857},{8,0,902},{8,0,910},{10,0,879},{11,11, +34},{140,0,726},{136,0,692},{6,10,193},{7,10,240},{7,10,1682},{10,10,51},{10,10, +640},{11,10,410},{13,10,82},{14,10,247},{14,10,331},{142,10,377},{6,0,823},{134, +0,983},{139,10,411},{132,0,305},{136,10,633},{138,11,203},{134,0,681},{6,11,326} +,{7,11,677},{137,11,425},{5,0,214},{7,0,603},{8,0,611},{9,0,686},{10,0,88},{11,0 +,459},{11,0,496},{12,0,463},{12,0,590},{141,0,0},{136,0,1004},{142,0,23},{134,0, +1703},{147,11,8},{145,11,56},{135,0,1443},{4,10,237},{135,10,514},{6,0,714},{145 +,0,19},{5,11,358},{7,11,473},{7,11,1184},{10,11,662},{13,11,212},{13,11,304},{13 +,11,333},{145,11,98},{4,0,737},{10,0,98},{11,0,294},{12,0,60},{12,0,437},{13,0, +64},{13,0,380},{142,0,430},{6,10,392},{7,10,65},{135,10,2019},{6,0,1758},{8,0, +520},{9,0,345},{9,0,403},{142,0,350},{5,0,47},{10,0,242},{138,0,579},{5,0,139},{ +7,0,1168},{138,0,539},{134,0,1459},{13,0,388},{141,11,388},{134,0,253},{7,10, +1260},{135,10,1790},{9,10,222},{10,0,252},{139,10,900},{140,0,745},{133,11,946}, +{4,0,107},{7,0,613},{8,0,439},{8,0,504},{9,0,501},{10,0,383},{139,0,477},{135,11 +,1485},{132,0,871},{7,11,411},{7,11,590},{8,11,631},{9,11,323},{10,11,355},{11, +11,491},{12,11,143},{12,11,402},{13,11,73},{14,11,408},{15,11,107},{146,11,71},{ +132,0,229},{132,0,903},{140,0,71},{133,0,549},{4,0,47},{6,0,373},{7,0,452},{7,0, +543},{7,0,1828},{7,0,1856},{9,0,6},{11,0,257},{139,0,391},{7,11,1467},{8,11,328} +,{10,11,544},{11,11,955},{13,11,320},{145,11,83},{5,0,980},{134,0,1754},{136,0, +865},{5,0,705},{137,0,606},{7,0,161},{8,10,201},{136,10,605},{143,11,35},{5,11, +835},{6,11,483},{140,10,224},{7,0,536},{7,0,1331},{136,0,143},{134,0,1388},{5,0, +724},{10,0,305},{11,0,151},{12,0,33},{12,0,121},{12,0,381},{17,0,3},{17,0,27},{ +17,0,78},{18,0,18},{19,0,54},{149,0,5},{4,10,523},{133,10,638},{5,0,19},{134,0, +533},{5,0,395},{5,0,951},{134,0,1776},{135,0,1908},{132,0,846},{6,10,242},{7,10, +227},{7,10,1581},{8,10,104},{9,10,113},{9,10,220},{9,10,427},{10,0,74},{10,10, +239},{11,0,663},{11,10,579},{11,10,1023},{12,0,210},{13,0,166},{13,0,310},{13,10 +,4},{13,10,204},{13,10,316},{14,0,373},{18,0,95},{19,0,43},{148,10,86},{9,11,716 +},{11,11,108},{13,11,123},{14,11,252},{19,11,38},{21,11,3},{151,11,11},{8,0,372} +,{9,0,122},{138,0,175},{132,11,677},{7,11,1374},{136,11,540},{135,10,861},{132,0 +,695},{7,0,497},{9,0,387},{147,0,81},{136,0,937},{134,0,718},{7,0,1328},{136,10, +494},{132,11,331},{5,11,747},{134,0,1581},{5,0,284},{6,0,49},{6,0,350},{7,0,1},{ +7,0,377},{7,0,1693},{8,0,18},{8,0,678},{9,0,161},{9,0,585},{9,0,671},{9,0,839},{ +11,0,912},{141,0,427},{7,10,1306},{8,10,505},{9,10,482},{10,10,126},{11,10,225}, +{12,10,347},{12,10,449},{13,10,19},{14,10,218},{142,10,435},{10,10,764},{12,10, +120},{13,10,39},{145,10,127},{4,0,597},{133,10,268},{134,0,1094},{4,0,1008},{134 +,0,1973},{132,0,811},{139,0,908},{135,0,1471},{133,11,326},{4,10,384},{135,10, +1022},{4,11,691},{7,0,1935},{7,11,1935},{8,0,324},{8,11,324},{9,11,35},{10,11, +680},{11,11,364},{12,0,42},{12,11,42},{13,11,357},{146,11,16},{135,0,2014},{6,11 +,32},{7,0,2007},{7,11,385},{7,11,757},{7,11,1916},{8,11,37},{8,11,94},{8,11,711} +,{9,0,101},{9,0,450},{9,11,541},{10,0,66},{10,0,842},{10,11,162},{10,11,795},{11 +,0,536},{11,11,989},{11,11,1010},{12,0,587},{12,11,14},{142,11,308},{139,0,586}, +{135,10,1703},{7,0,1077},{9,10,159},{11,0,28},{140,10,603},{6,0,1221},{136,10, +583},{6,11,152},{6,11,349},{6,11,1682},{7,11,1252},{8,11,112},{9,11,435},{9,11, +668},{10,11,290},{10,11,319},{10,11,815},{11,11,180},{11,11,837},{12,11,240},{13 +,11,152},{13,11,219},{142,11,158},{139,0,62},{132,10,515},{8,10,632},{8,10,697}, +{137,10,854},{134,0,1766},{132,11,581},{6,11,126},{7,11,573},{8,11,397},{142,11, +44},{150,0,28},{4,10,136},{5,10,551},{11,0,670},{150,0,25},{6,0,1665},{7,0,256}, +{7,0,1388},{138,0,499},{4,0,22},{5,0,10},{7,0,1576},{136,0,97},{134,10,1782},{5, +0,481},{7,10,1287},{9,10,44},{10,10,552},{10,10,642},{11,10,839},{12,10,274},{12 +,10,275},{12,10,372},{13,10,91},{142,10,125},{133,11,926},{7,11,1232},{137,11, +531},{6,0,134},{7,0,437},{7,0,1824},{9,0,37},{14,0,285},{142,0,371},{7,0,486},{8 +,0,155},{11,0,93},{140,0,164},{6,0,1391},{134,0,1442},{133,11,670},{133,0,591},{ +6,10,147},{7,10,886},{7,11,1957},{9,10,753},{138,10,268},{5,0,380},{5,0,650},{7, +0,1173},{136,0,310},{4,0,364},{7,0,1156},{7,0,1187},{137,0,409},{135,11,1621},{ +134,0,482},{133,11,506},{4,0,781},{6,0,487},{7,0,926},{8,0,263},{139,0,500},{138 +,10,137},{135,11,242},{139,11,96},{133,10,414},{135,10,1762},{134,0,804},{5,11, +834},{7,11,1202},{8,11,14},{9,11,481},{137,11,880},{134,10,599},{4,0,94},{135,0, +1265},{4,0,415},{132,0,417},{5,0,348},{6,0,522},{6,10,1749},{7,11,1526},{138,11, +465},{134,10,1627},{132,0,1012},{132,10,488},{4,11,357},{6,11,172},{7,11,143},{ +137,11,413},{4,10,83},{4,11,590},{146,11,76},{140,10,676},{7,11,287},{8,11,355}, +{9,11,293},{137,11,743},{134,10,278},{5,11,169},{6,0,1803},{7,11,333},{8,11,45}, +{18,0,165},{152,0,21},{12,10,97},{140,11,97},{4,0,408},{4,0,741},{135,0,500},{ +132,11,198},{7,10,388},{7,10,644},{139,10,781},{4,11,24},{5,11,140},{5,11,185},{ +7,11,1500},{11,11,565},{139,11,838},{6,0,1321},{7,10,229},{8,10,59},{9,0,257},{9 +,10,190},{10,10,378},{140,10,191},{4,11,334},{133,11,593},{135,11,1885},{134,0, +1138},{4,0,249},{6,0,73},{135,0,177},{133,0,576},{142,0,231},{137,0,288},{132,10 +,660},{7,10,1035},{138,10,737},{135,0,1487},{6,0,989},{7,10,690},{9,0,433},{9,10 +,587},{140,10,521},{7,0,1264},{7,0,1678},{11,0,945},{12,0,341},{12,0,471},{140,0 +,569},{132,11,709},{133,11,897},{5,11,224},{13,11,174},{146,11,52},{135,11,1840} +,{134,10,1744},{4,10,733},{9,10,194},{10,10,92},{11,10,198},{12,0,87},{12,10,84} +,{13,10,128},{144,0,74},{140,0,779},{135,0,538},{4,11,608},{133,11,497},{133,0, +413},{7,11,1375},{7,11,1466},{138,11,331},{136,0,495},{6,11,540},{136,11,136},{7 +,0,54},{8,0,312},{10,0,191},{10,0,614},{140,0,567},{5,11,999},{6,0,468},{7,0,567 +},{7,0,1478},{8,0,530},{142,0,290},{4,11,299},{7,10,306},{135,11,1004},{142,11, +296},{134,0,1484},{133,10,979},{6,0,609},{9,0,815},{12,11,137},{14,11,9},{14,11, +24},{142,11,64},{133,11,456},{6,0,484},{135,0,822},{133,10,178},{136,11,180},{ +132,11,755},{137,0,900},{135,0,1335},{6,0,1724},{135,0,2022},{135,11,1139},{4,10 +,390},{133,0,640},{6,0,1831},{138,11,633},{135,11,566},{4,11,890},{5,11,805},{5, +11,819},{5,11,961},{6,11,396},{6,11,1631},{6,11,1678},{7,11,1967},{7,11,2041},{9 +,11,630},{11,11,8},{11,11,1019},{12,11,176},{13,11,225},{14,11,292},{149,11,24}, +{132,0,474},{134,0,1103},{135,0,1504},{134,0,1576},{6,0,961},{6,0,1034},{140,0, +655},{11,11,514},{149,11,20},{5,0,305},{135,11,1815},{7,11,1505},{10,11,190},{10 +,11,634},{11,11,792},{12,11,358},{140,11,447},{5,11,0},{6,11,536},{7,11,604},{13 +,11,445},{145,11,126},{5,10,105},{135,0,1236},{4,0,480},{6,0,217},{6,0,302},{6,0 +,1642},{6,11,232},{6,11,412},{7,0,130},{7,0,837},{7,0,1321},{7,0,1547},{7,0,1657 +},{7,11,1074},{8,0,429},{8,11,9},{8,11,157},{8,11,786},{9,0,228},{9,11,196},{9, +11,352},{9,11,457},{10,11,337},{11,11,232},{11,11,877},{12,11,480},{12,11,546},{ +13,0,289},{13,0,343},{147,0,101},{5,10,438},{7,11,958},{9,10,694},{12,10,627},{ +13,10,210},{141,11,38},{4,11,382},{136,11,579},{7,0,278},{10,0,739},{11,0,708},{ +141,0,348},{4,11,212},{135,11,1206},{135,11,1898},{6,0,708},{6,0,1344},{152,10, +11},{137,11,768},{134,0,1840},{140,0,233},{8,10,25},{138,10,826},{5,11,655},{134 +,0,2017},{6,0,1488},{139,11,290},{132,10,308},{134,0,1590},{134,0,1800},{134,0, +1259},{6,11,231},{7,11,95},{8,11,423},{144,0,28},{133,11,300},{135,10,150},{136, +10,649},{7,11,1874},{137,11,641},{6,11,237},{7,11,611},{8,11,100},{9,11,416},{11 +,11,335},{12,11,173},{146,11,101},{137,0,45},{134,10,521},{14,11,26},{17,0,36},{ +146,11,150},{5,10,339},{7,0,1442},{14,0,22},{15,10,41},{15,10,166},{147,10,66},{ +6,11,581},{7,11,1119},{136,0,378},{134,0,1507},{147,11,117},{139,0,39},{134,0, +1054},{6,0,363},{7,0,1955},{136,0,725},{134,0,2036},{133,11,199},{6,0,1871},{9,0 +,935},{9,0,961},{9,0,1004},{9,0,1016},{12,0,805},{12,0,852},{12,0,853},{12,0,869 +},{12,0,882},{12,0,896},{12,0,906},{12,0,917},{12,0,940},{15,0,170},{15,0,176},{ +15,0,188},{15,0,201},{15,0,205},{15,0,212},{15,0,234},{15,0,244},{18,0,181},{18, +0,193},{18,0,196},{18,0,201},{18,0,202},{18,0,210},{18,0,217},{18,0,235},{18,0, +236},{18,0,237},{21,0,54},{21,0,55},{21,0,58},{21,0,59},{152,0,22},{134,10,1628} +,{137,0,805},{5,0,813},{135,0,2046},{142,11,42},{5,0,712},{6,0,1240},{11,0,17},{ +13,0,321},{144,0,67},{132,0,617},{135,10,829},{6,0,320},{7,0,781},{7,0,1921},{9, +0,55},{10,0,186},{10,0,273},{10,0,664},{10,0,801},{11,0,996},{11,0,997},{13,0, +157},{142,0,170},{136,0,271},{5,10,486},{135,10,1349},{18,11,91},{147,11,70},{7, +10,1635},{8,10,17},{10,0,445},{138,10,295},{136,11,404},{7,0,103},{7,0,863},{11, +0,184},{145,0,62},{138,10,558},{137,0,659},{6,11,312},{6,11,1715},{10,11,584},{ +11,11,546},{11,11,692},{12,11,259},{12,11,295},{13,11,46},{141,11,154},{134,0, +676},{132,11,588},{4,11,231},{5,11,61},{6,11,104},{7,11,729},{7,11,964},{7,11, +1658},{140,11,414},{6,11,263},{138,11,757},{11,0,337},{142,0,303},{135,11,1363}, +{132,11,320},{140,0,506},{134,10,447},{5,0,77},{7,0,1455},{10,0,843},{147,0,73}, +{7,10,577},{7,10,1432},{9,10,475},{9,10,505},{9,10,526},{9,10,609},{9,10,689},{9 +,10,726},{9,10,735},{9,10,738},{10,10,556},{10,10,674},{10,10,684},{11,10,89},{ +11,10,202},{11,10,272},{11,10,380},{11,10,415},{11,10,505},{11,10,537},{11,10, +550},{11,10,562},{11,10,640},{11,10,667},{11,10,688},{11,10,847},{11,10,927},{11 +,10,930},{11,10,940},{12,10,144},{12,10,325},{12,10,329},{12,10,389},{12,10,403} +,{12,10,451},{12,10,515},{12,10,604},{12,10,616},{12,10,626},{13,10,66},{13,10, +131},{13,10,167},{13,10,236},{13,10,368},{13,10,411},{13,10,434},{13,10,453},{13 +,10,461},{13,10,474},{14,10,59},{14,10,60},{14,10,139},{14,10,152},{14,10,276},{ +14,10,353},{14,10,402},{15,10,28},{15,10,81},{15,10,123},{15,10,152},{18,10,136} +,{148,10,88},{132,0,458},{135,0,1420},{4,10,609},{4,11,405},{6,0,109},{7,10,756} +,{7,11,817},{9,10,544},{10,0,382},{11,10,413},{14,10,307},{14,11,58},{16,10,25}, +{17,11,37},{146,11,124},{5,11,974},{6,0,330},{7,0,1084},{139,0,142},{4,10,930},{ +133,10,947},{5,10,939},{142,11,394},{16,0,91},{145,0,87},{5,10,962},{5,11,235},{ +7,11,1239},{11,11,131},{140,11,370},{5,10,651},{8,10,170},{9,10,61},{9,10,63},{ +10,10,23},{10,10,37},{10,10,834},{11,0,492},{11,10,4},{11,10,281},{11,10,503},{ +11,10,677},{12,10,96},{12,10,130},{12,10,244},{14,10,5},{14,10,40},{14,10,162},{ +14,10,202},{146,10,133},{4,10,406},{5,10,579},{12,10,492},{150,10,15},{9,11,137} +,{138,11,221},{134,0,1239},{11,0,211},{140,0,145},{7,11,390},{138,11,140},{135, +11,1418},{135,11,1144},{134,0,1049},{6,10,17},{7,0,321},{7,10,1001},{7,10,1982}, +{9,10,886},{10,10,489},{10,10,800},{11,10,782},{12,10,320},{13,10,467},{14,10, +145},{14,10,387},{143,10,119},{145,10,17},{5,11,407},{11,11,489},{19,11,37},{20, +11,73},{150,11,38},{133,10,458},{135,0,1985},{7,10,1983},{8,10,0},{8,10,171},{9, +10,120},{9,10,732},{10,10,473},{11,10,656},{11,10,998},{18,10,0},{18,10,2},{147, +10,21},{5,11,325},{7,11,1483},{8,11,5},{8,11,227},{9,11,105},{10,11,585},{140,11 +,614},{136,0,122},{132,0,234},{135,11,1196},{6,0,976},{6,0,1098},{134,0,1441},{7 +,0,253},{136,0,549},{6,11,621},{13,11,504},{144,11,19},{132,10,519},{5,0,430},{5 +,0,932},{6,0,131},{7,0,417},{9,0,522},{11,0,314},{141,0,390},{14,0,149},{14,0, +399},{143,0,57},{5,10,907},{6,10,31},{6,11,218},{7,10,491},{7,10,530},{8,10,592} +,{11,10,53},{11,10,779},{12,10,167},{12,10,411},{14,10,14},{14,10,136},{15,10,72 +},{16,10,17},{144,10,72},{140,11,330},{7,11,454},{7,11,782},{136,11,768},{132,0, +507},{10,11,676},{140,11,462},{4,10,208},{5,10,106},{6,0,630},{6,10,531},{8,10, +408},{9,0,811},{9,10,188},{138,10,572},{4,0,343},{5,0,511},{134,10,1693},{134,11 +,164},{132,0,448},{7,0,455},{138,0,591},{135,0,1381},{12,10,441},{150,11,50},{9, +10,449},{10,10,192},{138,10,740},{4,10,241},{134,0,575},{134,0,1175},{134,0,653} +,{134,0,1761},{134,0,1198},{132,10,259},{6,11,343},{7,11,195},{9,11,226},{10,11, +197},{10,11,575},{11,11,502},{139,11,899},{7,0,1127},{7,0,1572},{10,0,297},{10,0 +,422},{11,0,764},{11,0,810},{12,0,264},{13,0,102},{13,0,300},{13,0,484},{14,0, +147},{14,0,229},{17,0,71},{18,0,118},{147,0,120},{135,11,666},{132,0,678},{4,10, +173},{5,10,312},{5,10,512},{135,10,1285},{7,10,1603},{7,10,1691},{9,10,464},{11, +10,195},{12,10,279},{12,10,448},{14,10,11},{147,10,102},{16,0,99},{146,0,164},{7 +,11,1125},{9,11,143},{11,11,61},{14,11,405},{150,11,21},{137,11,260},{4,10,452}, +{5,10,583},{5,10,817},{6,10,433},{7,10,593},{7,10,720},{7,10,1378},{8,10,161},{9 +,10,284},{10,10,313},{139,10,886},{132,10,547},{136,10,722},{14,0,35},{142,0,191 +},{141,0,45},{138,0,121},{132,0,125},{134,0,1622},{133,11,959},{8,10,420},{139, +10,193},{132,0,721},{135,10,409},{136,0,145},{7,0,792},{8,0,147},{8,11,173},{10, +0,821},{11,0,970},{139,0,1021},{134,11,266},{132,0,715},{7,0,1999},{138,10,308}, +{133,0,531},{5,0,168},{5,0,930},{8,0,74},{9,0,623},{12,0,500},{140,0,579},{144,0 +,65},{138,11,246},{6,0,220},{7,0,1101},{13,0,105},{142,11,314},{5,10,1002},{136, +10,745},{134,0,960},{20,0,0},{148,11,0},{4,0,1005},{4,10,239},{6,10,477},{7,10, +1607},{11,10,68},{139,10,617},{6,0,19},{7,0,1413},{139,0,428},{149,10,13},{7,0, +96},{8,0,401},{8,0,703},{8,11,300},{137,0,896},{134,0,1595},{145,0,116},{136,0, +1021},{7,0,1961},{7,0,1965},{7,0,2030},{8,0,150},{8,0,702},{8,0,737},{8,0,750},{ +140,0,366},{11,11,75},{142,11,267},{132,10,367},{5,11,427},{5,11,734},{7,11,478} +,{8,0,800},{8,11,52},{9,0,148},{9,0,872},{9,0,890},{11,0,309},{11,0,1001},{13,0, +267},{141,0,323},{7,11,239},{11,11,217},{142,11,165},{132,11,323},{140,11,419},{ +13,0,299},{142,0,75},{6,11,87},{6,11,1734},{7,11,20},{7,11,1056},{8,11,732},{9, +11,406},{9,11,911},{138,11,694},{134,0,1383},{132,10,694},{133,11,613},{137,0, +779},{4,0,598},{140,10,687},{6,0,970},{135,0,424},{133,0,547},{7,11,32},{7,11, +984},{8,11,85},{8,11,709},{9,11,579},{9,11,847},{9,11,856},{10,11,799},{11,11, +258},{11,11,1007},{12,11,331},{12,11,615},{13,11,188},{13,11,435},{14,11,8},{15, +11,165},{16,11,27},{148,11,40},{6,0,1222},{134,0,1385},{132,0,876},{138,11,151}, +{135,10,213},{4,11,167},{135,11,82},{133,0,133},{6,11,24},{7,11,74},{7,11,678},{ +137,11,258},{5,11,62},{6,11,534},{7,11,684},{7,11,1043},{7,11,1072},{8,11,280},{ +8,11,541},{8,11,686},{10,11,519},{11,11,252},{140,11,282},{136,0,187},{8,0,8},{ +10,0,0},{10,0,818},{139,0,988},{132,11,359},{7,10,1672},{11,0,429},{143,0,51},{ +136,0,685},{5,11,211},{7,11,88},{136,11,627},{134,0,472},{136,0,132},{6,11,145}, +{141,11,336},{4,10,751},{11,10,390},{140,10,32},{4,10,409},{4,11,263},{5,10,78}, +{6,0,938},{134,0,1060},{137,0,874},{4,11,916},{6,10,473},{7,10,1602},{8,0,774},{ +10,0,670},{10,10,698},{12,0,51},{12,10,212},{13,10,307},{145,10,105},{146,0,92}, +{143,10,156},{132,0,830},{137,0,701},{4,11,599},{6,11,1634},{7,11,5},{7,11,55},{ +7,11,67},{7,11,97},{7,11,691},{7,11,979},{7,11,1697},{8,11,207},{8,11,214},{8,11 +,231},{8,11,294},{8,11,336},{8,11,428},{8,11,451},{8,11,460},{8,11,471},{8,11, +622},{8,11,626},{8,11,679},{8,11,759},{8,11,829},{9,11,11},{9,11,246},{9,11,484} +,{9,11,573},{9,11,706},{9,11,762},{9,11,798},{9,11,855},{9,11,870},{9,11,912},{ +10,11,303},{10,11,335},{10,11,424},{10,11,461},{10,11,543},{10,11,759},{10,11, +814},{11,11,59},{11,11,199},{11,11,235},{11,11,475},{11,11,590},{11,11,929},{11, +11,963},{12,11,114},{12,11,182},{12,11,226},{12,11,332},{12,11,439},{12,11,575}, +{12,11,598},{13,11,8},{13,11,125},{13,11,194},{13,11,287},{14,11,197},{14,11,383 +},{15,11,53},{17,11,63},{19,11,46},{19,11,98},{19,11,106},{148,11,85},{4,0,127}, +{5,0,350},{6,0,356},{8,0,426},{9,0,572},{10,0,247},{139,0,312},{134,0,1215},{6,0 +,59},{7,11,1853},{9,0,603},{10,11,437},{141,0,397},{134,0,1762},{147,11,126},{ +135,10,883},{13,0,293},{142,0,56},{133,10,617},{139,10,50},{5,11,187},{7,10,1518 +},{139,10,694},{135,0,441},{6,0,111},{7,0,4},{8,0,163},{8,0,776},{138,0,566},{ +132,0,806},{4,11,215},{9,11,38},{10,11,3},{11,11,23},{11,11,127},{139,11,796},{4 +,10,546},{7,10,2042},{142,0,233},{135,0,1994},{134,0,1739},{135,11,1530},{136,0, +393},{5,0,297},{7,0,1038},{14,0,359},{19,0,52},{148,0,47},{135,0,309},{4,10,313} +,{133,10,577},{8,10,184},{141,10,433},{135,10,935},{12,10,186},{12,10,292},{14, +10,100},{146,10,70},{136,0,363},{11,10,402},{12,10,109},{12,10,431},{13,10,179}, +{13,10,206},{14,0,175},{14,10,217},{16,10,3},{148,10,53},{5,10,886},{6,10,46},{6 +,10,1790},{7,10,14},{7,10,732},{7,10,1654},{8,10,95},{8,10,327},{8,10,616},{9,10 +,892},{10,10,598},{10,10,769},{11,10,134},{11,10,747},{12,10,378},{142,10,97},{ +136,0,666},{135,0,1675},{6,0,655},{134,0,1600},{135,0,808},{133,10,1021},{4,11, +28},{5,11,440},{7,11,248},{11,11,833},{140,11,344},{134,11,1654},{132,0,280},{ +140,0,54},{4,0,421},{133,0,548},{132,10,153},{6,11,339},{135,11,923},{133,11,853 +},{133,10,798},{132,10,587},{6,11,249},{7,11,1234},{139,11,573},{6,10,598},{7,10 +,42},{8,10,695},{10,10,212},{11,10,158},{14,10,196},{145,10,85},{5,10,957},{5,10 +,1008},{135,0,249},{4,10,129},{135,10,465},{6,0,254},{7,0,842},{7,0,1659},{7,10, +908},{7,10,1201},{9,0,109},{9,10,755},{10,0,103},{11,10,906},{12,10,527},{146,10 +,7},{5,0,262},{136,10,450},{144,0,1},{10,11,201},{142,11,319},{7,11,49},{7,11, +392},{8,11,20},{8,11,172},{8,11,690},{9,11,383},{9,11,845},{10,11,48},{11,11,293 +},{11,11,832},{11,11,920},{141,11,221},{5,11,858},{133,11,992},{134,0,805},{139, +10,1003},{6,0,1630},{134,11,307},{7,11,1512},{135,11,1794},{6,11,268},{137,11,62 +},{135,10,1868},{133,0,671},{4,0,989},{8,0,972},{136,0,998},{132,11,423},{132,0, +889},{135,0,1382},{135,0,1910},{7,10,965},{7,10,1460},{135,10,1604},{4,0,627},{5 +,0,775},{138,11,106},{134,11,348},{7,0,202},{11,0,362},{11,0,948},{140,0,388},{ +138,11,771},{6,11,613},{136,11,223},{6,0,560},{7,0,451},{8,0,389},{12,0,490},{13 +,0,16},{13,0,215},{13,0,351},{18,0,132},{147,0,125},{135,0,841},{136,0,566},{136 +,0,938},{132,11,670},{5,0,912},{6,0,1695},{140,11,55},{9,11,40},{139,11,136},{7, +0,1361},{7,10,982},{10,10,32},{143,10,56},{11,11,259},{140,11,270},{5,0,236},{6, +0,572},{8,0,492},{11,0,618},{144,0,56},{8,11,572},{9,11,310},{9,11,682},{137,11, +698},{134,0,1854},{5,0,190},{136,0,318},{133,10,435},{135,0,1376},{4,11,296},{6, +11,352},{7,11,401},{7,11,1410},{7,11,1594},{7,11,1674},{8,11,63},{8,11,660},{137 +,11,74},{5,10,85},{6,10,419},{7,0,349},{7,10,305},{7,10,361},{7,10,1337},{8,10, +71},{140,10,519},{4,11,139},{4,11,388},{140,11,188},{6,0,1972},{6,0,2013},{8,0, +951},{10,0,947},{10,0,974},{10,0,1018},{142,0,476},{140,10,688},{135,10,740},{5, +10,691},{7,10,345},{9,10,94},{140,10,169},{5,10,183},{6,10,582},{9,0,344},{10,10 +,679},{140,10,435},{135,10,511},{132,0,850},{8,11,441},{10,11,314},{143,11,3},{7 +,10,1993},{136,10,684},{4,11,747},{6,10,583},{6,11,290},{7,11,649},{7,11,1479},{ +135,11,1583},{133,11,232},{133,10,704},{134,0,910},{4,10,179},{5,10,198},{133,10 +,697},{7,10,347},{7,10,971},{8,10,181},{138,10,711},{136,11,525},{14,0,19},{14,0 +,28},{144,0,29},{7,0,85},{7,0,247},{8,0,585},{138,0,163},{4,0,487},{7,11,472},{7 +,11,1801},{10,11,748},{141,11,458},{4,10,243},{5,10,203},{7,10,19},{7,10,71},{7, +10,113},{10,10,405},{11,10,357},{142,10,240},{7,10,1450},{139,10,99},{132,11,425 +},{138,0,145},{147,0,83},{6,10,492},{137,11,247},{4,0,1013},{134,0,2033},{5,10, +134},{6,10,408},{6,10,495},{135,10,1593},{135,0,1922},{134,11,1768},{4,0,124},{ +10,0,457},{11,0,121},{11,0,169},{11,0,870},{11,0,874},{12,0,214},{14,0,187},{143 +,0,77},{5,0,557},{135,0,1457},{139,0,66},{5,11,943},{6,11,1779},{142,10,4},{4,10 +,248},{4,10,665},{7,10,137},{137,10,349},{5,11,245},{6,11,576},{7,0,1193},{7,11, +582},{136,11,225},{144,0,82},{7,10,1270},{139,10,612},{5,0,454},{10,0,352},{138, +11,352},{5,10,371},{7,10,563},{146,0,57},{135,0,1333},{6,0,107},{6,11,610},{7,0, +638},{7,0,1632},{137,0,396},{5,0,370},{134,0,1756},{4,10,374},{7,10,547},{7,10, +1700},{7,10,1833},{139,10,858},{133,0,204},{6,0,1305},{9,10,311},{141,10,42},{5, +0,970},{134,0,1706},{6,10,1647},{7,10,1552},{7,10,2010},{9,10,494},{137,10,509}, +{13,11,455},{15,11,99},{15,11,129},{144,11,68},{135,0,3},{4,0,35},{5,0,121},{5,0 +,483},{5,0,685},{6,0,489},{6,0,782},{6,0,1032},{7,0,1204},{136,0,394},{4,0,921}, +{133,0,1007},{8,11,360},{138,11,63},{135,0,1696},{134,0,1519},{132,11,443},{135, +11,944},{6,10,123},{7,10,214},{9,10,728},{10,10,157},{11,10,346},{11,10,662},{ +143,10,106},{137,0,981},{135,10,1435},{134,0,1072},{132,0,712},{134,0,1629},{134 +,0,728},{4,11,298},{137,11,483},{5,11,164},{6,0,1177},{6,0,1271},{7,11,121},{142 +,11,189},{4,10,707},{5,10,588},{6,10,393},{7,0,1608},{13,10,106},{18,10,49},{147 +,10,41},{23,0,16},{151,11,16},{6,10,211},{7,10,1690},{11,10,486},{140,10,369},{ +133,0,485},{19,11,15},{149,11,27},{4,11,172},{9,11,611},{10,11,436},{12,11,673}, +{141,11,255},{5,11,844},{10,11,484},{11,11,754},{12,11,457},{14,11,171},{14,11, +389},{146,11,153},{4,0,285},{5,0,27},{5,0,317},{6,0,301},{7,0,7},{8,0,153},{10,0 +,766},{11,0,468},{12,0,467},{141,0,143},{134,0,1462},{9,11,263},{10,11,147},{138 +,11,492},{133,11,537},{6,0,1945},{6,0,1986},{6,0,1991},{134,0,2038},{134,10,219} +,{137,11,842},{5,10,582},{6,10,1646},{7,10,99},{7,10,1962},{7,10,1986},{8,10,515 +},{8,10,773},{9,10,23},{9,10,491},{12,10,620},{14,0,52},{14,10,93},{145,0,50},{ +138,11,97},{5,10,851},{20,0,21},{148,0,44},{136,0,819},{139,0,917},{5,11,230},{5 +,11,392},{6,11,420},{8,10,762},{8,10,812},{9,10,910},{9,11,568},{140,11,612},{ +135,0,784},{15,0,135},{143,11,135},{10,0,454},{140,0,324},{4,11,0},{5,11,41},{7, +11,1459},{7,11,1469},{7,11,1618},{7,11,1859},{9,11,549},{139,11,905},{4,10,98},{ +7,10,1365},{9,10,422},{9,10,670},{10,10,775},{11,10,210},{13,10,26},{13,10,457}, +{141,10,476},{6,0,1719},{6,0,1735},{7,0,2016},{7,0,2020},{8,0,837},{137,0,852},{ +133,11,696},{135,0,852},{132,0,952},{134,10,1730},{132,11,771},{138,0,568},{137, +0,448},{139,0,146},{8,0,67},{138,0,419},{133,11,921},{137,10,147},{134,0,1826},{ +10,0,657},{14,0,297},{142,0,361},{6,0,666},{6,0,767},{134,0,1542},{139,0,729},{6 +,11,180},{7,11,1137},{8,11,751},{139,11,805},{4,11,183},{7,11,271},{11,11,824},{ +11,11,952},{13,11,278},{13,11,339},{13,11,482},{14,11,424},{148,11,99},{4,0,669} +,{5,11,477},{5,11,596},{6,11,505},{7,11,1221},{11,11,907},{12,11,209},{141,11, +214},{135,11,1215},{5,0,402},{6,10,30},{11,10,56},{139,10,305},{7,11,564},{142, +11,168},{139,0,152},{7,0,912},{135,10,1614},{4,10,150},{5,10,303},{134,10,327},{ +7,0,320},{8,0,51},{9,0,868},{10,0,833},{12,0,481},{12,0,570},{148,0,106},{132,0, +445},{7,11,274},{11,11,263},{11,11,479},{11,11,507},{140,11,277},{6,11,1645},{8, +10,192},{10,0,555},{10,10,78},{11,0,308},{13,10,359},{147,0,95},{135,10,786},{6, +11,92},{6,11,188},{7,11,1269},{7,11,1524},{7,11,1876},{10,11,228},{139,11,1020}, +{4,11,459},{133,11,966},{6,10,1638},{7,10,79},{7,10,496},{9,10,138},{10,10,336}, +{11,0,386},{12,10,412},{12,10,440},{142,10,305},{133,0,239},{7,0,83},{7,0,1990}, +{8,0,130},{139,0,720},{138,11,709},{4,0,143},{5,0,550},{133,0,752},{5,0,123},{6, +0,530},{7,0,348},{135,0,1419},{135,0,2024},{6,11,18},{7,11,179},{7,11,721},{7,11 +,932},{8,11,548},{8,11,757},{9,11,54},{9,11,65},{9,11,532},{9,11,844},{10,11,113 +},{10,11,117},{10,11,236},{10,11,315},{10,11,430},{10,11,798},{11,11,153},{11,11 +,351},{11,11,375},{12,11,78},{12,11,151},{12,11,392},{14,11,248},{143,11,23},{7, +10,204},{7,10,415},{8,10,42},{10,10,85},{139,10,564},{134,0,958},{133,11,965},{ +132,0,210},{135,11,1429},{138,11,480},{134,11,182},{139,11,345},{10,11,65},{10, +11,488},{138,11,497},{4,10,3},{5,10,247},{5,10,644},{7,10,744},{7,10,1207},{7,10 +,1225},{7,10,1909},{146,10,147},{132,0,430},{5,10,285},{9,10,67},{13,10,473},{ +143,10,82},{144,11,16},{7,11,1162},{9,11,588},{10,11,260},{151,10,8},{133,0,213} +,{138,0,7},{135,0,801},{134,11,1786},{135,11,308},{6,0,936},{134,0,1289},{133,0, +108},{132,0,885},{133,0,219},{139,0,587},{4,0,193},{5,0,916},{6,0,1041},{7,0,364 +},{10,0,398},{10,0,726},{11,0,317},{11,0,626},{12,0,142},{12,0,288},{12,0,678},{ +13,0,313},{15,0,113},{146,0,114},{135,0,1165},{6,0,241},{9,0,342},{10,0,729},{11 +,0,284},{11,0,445},{11,0,651},{11,0,863},{13,0,398},{146,0,99},{7,0,907},{136,0, +832},{4,10,29},{6,10,532},{7,10,1628},{7,10,1648},{9,0,303},{9,10,350},{10,10, +433},{11,10,97},{11,10,557},{11,10,745},{12,10,289},{12,10,335},{12,10,348},{12, +10,606},{13,10,116},{13,10,233},{13,10,466},{14,10,181},{14,10,209},{14,10,232}, +{14,10,236},{14,10,300},{16,10,41},{148,10,97},{7,10,1692},{7,11,423},{136,11, +588},{6,0,931},{134,0,1454},{5,10,501},{7,10,1704},{9,10,553},{11,10,520},{12,10 +,557},{141,10,249},{136,11,287},{4,0,562},{9,0,254},{139,0,879},{132,0,786},{14, +11,32},{18,11,85},{20,11,2},{152,11,16},{135,0,1294},{7,11,723},{135,11,1135},{6 +,0,216},{6,11,403},{7,0,901},{7,0,1343},{136,0,493},{7,11,719},{8,11,809},{136, +11,834},{5,11,210},{6,11,213},{7,11,60},{10,11,364},{139,11,135},{5,11,607},{7,0 +,341},{8,11,326},{8,11,490},{139,0,219},{4,11,701},{5,11,472},{5,11,639},{7,11, +1249},{9,11,758},{139,11,896},{135,11,380},{135,11,1947},{139,0,130},{135,0,1734 +},{10,0,115},{11,0,420},{12,0,154},{13,0,404},{14,0,346},{143,0,54},{134,10,129} +,{4,11,386},{7,11,41},{8,11,405},{9,11,497},{11,11,110},{11,11,360},{15,11,37},{ +144,11,84},{141,11,282},{5,11,46},{7,11,1452},{7,11,1480},{8,11,634},{140,11,472 +},{4,11,524},{136,11,810},{10,11,238},{141,11,33},{133,0,604},{5,0,1011},{136,0, +701},{8,0,856},{8,0,858},{8,0,879},{12,0,702},{142,0,447},{4,0,54},{5,0,666},{7, +0,1039},{7,0,1130},{9,0,195},{138,0,302},{4,10,25},{5,10,60},{6,10,504},{7,10, +614},{7,10,1155},{140,10,0},{7,10,1248},{11,10,621},{139,10,702},{133,11,997},{ +137,10,321},{134,0,1669},{134,0,1791},{4,10,379},{135,10,1397},{138,11,372},{5, +11,782},{5,11,829},{134,11,1738},{135,0,1228},{4,10,118},{6,10,274},{6,10,361},{ +7,10,75},{141,10,441},{132,0,623},{9,11,279},{10,11,407},{14,11,84},{150,11,18}, +{137,10,841},{135,0,798},{140,10,693},{5,10,314},{6,10,221},{7,10,419},{10,10, +650},{11,10,396},{12,10,156},{13,10,369},{14,10,333},{145,10,47},{135,11,1372},{ +7,0,122},{9,0,259},{10,0,84},{11,0,470},{12,0,541},{141,0,379},{134,0,837},{4,11 +,78},{5,11,96},{5,11,182},{7,11,1724},{7,11,1825},{8,0,1013},{10,11,394},{10,11, +471},{11,11,532},{14,11,340},{145,11,88},{134,0,577},{135,11,1964},{132,10,913}, +{134,0,460},{8,0,891},{10,0,901},{10,0,919},{10,0,932},{12,0,715},{12,0,728},{12 +,0,777},{14,0,457},{144,0,103},{5,0,82},{5,0,131},{7,0,1755},{8,0,31},{9,0,168}, +{9,0,764},{139,0,869},{136,10,475},{5,10,1016},{6,0,605},{9,11,601},{9,11,619},{ +10,11,505},{10,11,732},{11,11,355},{140,11,139},{7,10,602},{8,10,179},{10,10,781 +},{140,10,126},{134,0,1246},{6,10,329},{138,10,111},{6,11,215},{7,11,1028},{7,11 +,1473},{7,11,1721},{9,11,424},{138,11,779},{5,0,278},{137,0,68},{6,0,932},{6,0, +1084},{144,0,86},{4,0,163},{5,0,201},{5,0,307},{5,0,310},{6,0,335},{7,0,284},{7, +0,1660},{136,0,165},{136,0,781},{134,0,707},{6,0,33},{135,0,1244},{5,10,821},{6, +10,1687},{6,11,67},{7,11,258},{7,11,1630},{9,11,354},{9,11,675},{10,11,830},{14, +11,80},{145,11,80},{6,11,141},{7,11,225},{9,11,59},{9,11,607},{10,11,312},{11,11 +,687},{12,11,555},{13,11,373},{13,11,494},{148,11,58},{134,0,1113},{5,10,71},{7, +10,1407},{9,0,388},{9,10,704},{10,10,261},{10,10,619},{11,10,547},{11,10,619},{ +143,10,157},{7,0,1953},{136,0,720},{138,0,203},{7,10,2008},{9,10,337},{138,10, +517},{6,0,326},{7,0,677},{137,0,425},{139,11,81},{7,0,1316},{7,0,1412},{7,0,1839 +},{9,0,589},{11,0,241},{11,0,676},{11,0,811},{11,0,891},{12,0,140},{12,0,346},{ +12,0,479},{13,0,140},{13,0,381},{14,0,188},{18,0,30},{148,0,108},{5,0,416},{6,10 +,86},{6,10,603},{7,10,292},{7,10,561},{8,10,257},{8,10,382},{9,10,721},{9,10,778 +},{11,10,581},{140,10,466},{4,10,486},{133,10,491},{134,0,1300},{132,10,72},{6, +10,265},{7,0,847},{7,11,430},{139,11,46},{5,11,602},{6,11,106},{7,11,1786},{7,11 +,1821},{7,11,2018},{9,11,418},{137,11,763},{5,0,358},{7,0,535},{7,0,1184},{10,0, +662},{13,0,212},{13,0,304},{13,0,333},{145,0,98},{5,11,65},{6,11,416},{7,11,1720 +},{7,11,1924},{8,11,677},{10,11,109},{11,11,14},{11,11,70},{11,11,569},{11,11, +735},{15,11,153},{148,11,80},{6,0,1823},{8,0,839},{8,0,852},{8,0,903},{10,0,940} +,{12,0,707},{140,0,775},{135,11,1229},{6,0,1522},{140,0,654},{136,11,595},{139,0 +,163},{141,0,314},{132,0,978},{4,0,601},{6,0,2035},{137,10,234},{5,10,815},{6,10 +,1688},{134,10,1755},{133,0,946},{136,0,434},{6,10,197},{136,10,205},{7,0,411},{ +7,0,590},{8,0,631},{9,0,323},{10,0,355},{11,0,491},{12,0,143},{12,0,402},{13,0, +73},{14,0,408},{15,0,107},{146,0,71},{7,0,1467},{8,0,328},{10,0,544},{11,0,955}, +{12,0,13},{13,0,320},{145,0,83},{142,0,410},{11,0,511},{13,0,394},{14,0,298},{14 +,0,318},{146,0,103},{6,10,452},{7,10,312},{138,10,219},{138,10,589},{4,10,333},{ +9,10,176},{12,10,353},{141,10,187},{135,11,329},{132,11,469},{5,0,835},{134,0, +483},{134,11,1743},{5,11,929},{6,11,340},{8,11,376},{136,11,807},{134,10,1685},{ +132,0,677},{5,11,218},{7,11,1610},{138,11,83},{5,11,571},{135,11,1842},{132,11, +455},{137,0,70},{135,0,1405},{7,10,135},{8,10,7},{8,10,62},{9,10,243},{10,10,658 +},{10,10,697},{11,10,456},{139,10,756},{9,10,395},{138,10,79},{137,0,108},{6,11, +161},{7,11,372},{137,11,597},{132,11,349},{132,0,777},{132,0,331},{135,10,631},{ +133,0,747},{6,11,432},{6,11,608},{139,11,322},{138,10,835},{5,11,468},{7,11,1809 +},{10,11,325},{11,11,856},{12,11,345},{143,11,104},{133,11,223},{7,10,406},{7,10 +,459},{8,10,606},{139,10,726},{132,11,566},{142,0,68},{4,11,59},{135,11,1394},{6 +,11,436},{139,11,481},{4,11,48},{5,11,271},{135,11,953},{139,11,170},{5,11,610}, +{136,11,457},{133,11,755},{135,11,1217},{133,10,612},{132,11,197},{132,0,505},{4 +,10,372},{7,10,482},{8,10,158},{9,10,602},{9,10,615},{10,10,245},{10,10,678},{10 +,10,744},{11,10,248},{139,10,806},{133,0,326},{5,10,854},{135,10,1991},{4,0,691} +,{146,0,16},{6,0,628},{9,0,35},{10,0,680},{10,0,793},{11,0,364},{13,0,357},{143, +0,164},{138,0,654},{6,0,32},{7,0,385},{7,0,757},{7,0,1916},{8,0,37},{8,0,94},{8, +0,711},{9,0,541},{10,0,162},{10,0,795},{11,0,989},{11,0,1010},{12,0,14},{142,0, +308},{133,11,217},{6,0,152},{6,0,349},{6,0,1682},{7,0,1252},{8,0,112},{9,0,435}, +{9,0,668},{10,0,290},{10,0,319},{10,0,815},{11,0,180},{11,0,837},{12,0,240},{13, +0,152},{13,0,219},{142,0,158},{4,0,581},{134,0,726},{5,10,195},{135,10,1685},{6, +0,126},{7,0,573},{8,0,397},{142,0,44},{138,0,89},{7,10,1997},{8,10,730},{139,10, +1006},{134,0,1531},{134,0,1167},{5,0,926},{5,10,751},{140,0,203},{4,11,165},{7, +11,1398},{135,11,1829},{7,0,1232},{137,0,531},{135,10,821},{134,0,943},{133,0, +670},{4,0,880},{139,0,231},{134,0,1617},{135,0,1957},{5,11,9},{7,11,297},{7,11, +966},{140,11,306},{6,0,975},{134,0,985},{5,10,950},{5,10,994},{134,10,351},{12, +11,21},{151,11,7},{5,11,146},{6,11,411},{138,11,721},{7,0,242},{135,0,1942},{6, +11,177},{135,11,467},{5,0,421},{7,10,47},{137,10,684},{5,0,834},{7,0,1202},{8,0, +14},{9,0,481},{137,0,880},{138,0,465},{4,10,350},{6,0,688},{137,0,834},{132,0, +855},{4,0,357},{6,0,172},{7,0,143},{137,0,413},{133,11,200},{132,0,590},{7,10, +1812},{13,10,259},{13,10,356},{14,10,242},{147,10,114},{133,10,967},{4,10,473},{ +7,10,623},{8,10,808},{9,10,871},{9,10,893},{11,0,114},{11,10,431},{12,10,112},{ +12,10,217},{12,10,243},{12,10,562},{12,10,663},{12,10,683},{13,10,141},{13,10, +197},{13,10,227},{13,10,406},{13,10,487},{14,10,156},{14,10,203},{14,10,224},{14 +,10,256},{18,10,58},{150,10,0},{138,10,286},{4,10,222},{7,10,286},{136,10,629},{ +5,0,169},{7,0,333},{136,0,45},{134,11,481},{132,0,198},{4,0,24},{4,11,84},{5,0, +140},{5,0,185},{7,0,1500},{7,11,1482},{10,11,76},{10,11,142},{11,0,565},{139,0, +838},{133,0,585},{141,10,306},{133,11,1015},{4,11,315},{5,11,507},{135,11,1370}, +{136,10,146},{6,0,691},{134,0,1503},{4,0,334},{133,0,593},{4,10,465},{135,10, +1663},{142,11,173},{135,0,913},{6,11,1722},{140,0,116},{134,0,1360},{132,0,802}, +{8,11,222},{8,11,476},{9,11,238},{11,11,516},{11,11,575},{15,11,109},{146,11,100 +},{6,0,308},{7,10,138},{7,10,517},{9,0,673},{139,10,238},{132,0,709},{6,0,1876}, +{6,0,1895},{9,0,994},{9,0,1006},{12,0,829},{12,0,888},{12,0,891},{146,0,185},{ +148,10,94},{4,0,228},{133,0,897},{5,10,495},{7,0,1840},{7,10,834},{9,10,733},{ +139,10,378},{133,10,559},{6,10,21},{6,10,1737},{7,10,1444},{136,10,224},{4,0,608 +},{133,0,497},{6,11,40},{135,11,1781},{134,0,1573},{135,0,2039},{6,0,540},{136,0 +,136},{4,0,897},{5,0,786},{133,10,519},{6,0,1878},{6,0,1884},{9,0,938},{9,0,948} +,{9,0,955},{9,0,973},{9,0,1012},{12,0,895},{12,0,927},{143,0,254},{134,0,1469},{ +133,0,999},{4,0,299},{135,0,1004},{4,0,745},{133,0,578},{136,11,574},{133,0,456} +,{134,0,1457},{4,10,402},{135,0,1679},{7,0,693},{8,0,180},{8,10,323},{8,10,479}, +{140,0,163},{11,10,580},{142,10,201},{5,10,59},{135,10,672},{132,11,354},{146,10 +,34},{4,0,755},{135,11,1558},{7,0,1740},{146,0,48},{4,10,85},{135,10,549},{139,0 +,338},{133,10,94},{134,0,1091},{135,11,469},{5,11,830},{12,0,695},{12,0,704},{14 +,11,338},{20,0,113},{148,11,81},{135,0,1464},{6,10,11},{135,10,187},{135,0,975}, +{4,10,522},{141,0,335},{134,0,1979},{5,11,496},{135,11,203},{4,10,52},{135,10, +661},{7,0,1566},{8,0,269},{9,0,212},{9,0,718},{14,0,15},{14,0,132},{142,0,227},{ +4,0,890},{4,10,383},{5,0,805},{5,0,819},{5,0,961},{5,10,520},{6,0,396},{6,0,1631 +},{6,0,1678},{7,0,1967},{7,0,2041},{9,0,630},{11,0,8},{11,0,1019},{12,0,176},{13 +,0,225},{14,0,292},{149,0,24},{134,11,547},{135,11,1748},{5,11,88},{137,11,239}, +{146,11,128},{7,11,650},{135,11,1310},{4,10,281},{5,10,38},{7,10,194},{7,10,668} +,{7,10,1893},{137,10,397},{135,0,1815},{9,10,635},{139,10,559},{7,0,1505},{10,0, +190},{10,0,634},{11,0,792},{12,0,358},{140,0,447},{5,0,0},{6,0,536},{7,0,604},{ +13,0,445},{145,0,126},{7,11,1076},{9,11,80},{11,11,78},{11,11,421},{11,11,534},{ +140,11,545},{8,0,966},{10,0,1023},{14,11,369},{146,11,72},{135,11,1641},{6,0,232 +},{6,0,412},{7,0,1074},{8,0,9},{8,0,157},{8,0,786},{9,0,196},{9,0,352},{9,0,457} +,{10,0,337},{11,0,232},{11,0,877},{12,0,480},{140,0,546},{135,0,958},{4,0,382},{ +136,0,579},{4,0,212},{135,0,1206},{4,11,497},{5,11,657},{135,11,1584},{132,0,681 +},{8,0,971},{138,0,965},{5,10,448},{136,10,535},{14,0,16},{146,0,44},{11,0,584}, +{11,0,616},{11,11,584},{11,11,616},{14,0,275},{142,11,275},{136,11,13},{7,10,610 +},{135,10,1501},{7,11,642},{8,11,250},{11,11,123},{11,11,137},{13,11,48},{142,11 +,95},{133,0,655},{17,0,67},{147,0,74},{134,0,751},{134,0,1967},{6,0,231},{136,0, +423},{5,0,300},{138,0,1016},{4,10,319},{5,10,699},{138,10,673},{6,0,237},{6,10, +336},{7,0,611},{8,0,100},{8,10,552},{9,0,416},{9,10,285},{10,10,99},{11,0,335},{ +11,10,568},{12,0,173},{146,0,101},{134,0,1370},{7,10,1406},{9,10,218},{141,10, +222},{133,10,256},{135,0,1208},{14,11,213},{148,11,38},{6,0,1219},{135,11,1642}, +{13,0,417},{14,0,129},{143,0,15},{10,11,545},{140,11,301},{17,10,39},{148,10,36} +,{133,0,199},{4,11,904},{133,11,794},{12,0,427},{146,0,38},{134,0,949},{7,10,634 +},{136,0,665},{132,10,618},{135,10,259},{132,10,339},{133,11,761},{141,10,169},{ +132,10,759},{5,0,688},{7,0,539},{135,0,712},{7,11,386},{138,11,713},{134,0,1186} +,{6,11,7},{6,11,35},{7,11,147},{7,11,1069},{7,11,1568},{7,11,1575},{7,11,1917},{ +8,11,43},{8,11,208},{9,11,128},{9,11,866},{10,11,20},{11,11,981},{147,11,33},{7, +11,893},{8,10,482},{141,11,424},{6,0,312},{6,0,1715},{10,0,584},{11,0,546},{11,0 +,692},{12,0,259},{12,0,295},{13,0,46},{141,0,154},{5,10,336},{6,10,341},{6,10, +478},{6,10,1763},{136,10,386},{137,0,151},{132,0,588},{152,0,4},{6,11,322},{9,11 +,552},{11,11,274},{13,11,209},{13,11,499},{14,11,85},{15,11,126},{145,11,70},{ +135,10,73},{4,0,231},{5,0,61},{6,0,104},{7,0,729},{7,0,964},{7,0,1658},{140,0, +414},{6,0,263},{138,0,757},{135,10,1971},{4,0,612},{133,0,561},{132,0,320},{135, +10,1344},{8,11,83},{8,11,817},{9,11,28},{9,11,29},{9,11,885},{10,11,387},{11,11, +633},{11,11,740},{13,11,235},{13,11,254},{15,11,143},{143,11,146},{5,10,396},{ +134,10,501},{140,11,49},{132,0,225},{4,10,929},{5,10,799},{8,10,46},{136,10,740} +,{4,0,405},{7,0,817},{14,0,58},{17,0,37},{146,0,124},{133,0,974},{4,11,412},{133 +,11,581},{4,10,892},{133,10,770},{4,0,996},{134,0,2026},{4,0,527},{5,0,235},{7,0 +,1239},{11,0,131},{140,0,370},{7,11,421},{9,0,16},{141,0,386},{7,0,956},{7,0, +1157},{7,0,1506},{7,0,1606},{7,0,1615},{7,0,1619},{7,0,1736},{7,0,1775},{8,0,590 +},{9,0,324},{9,0,736},{9,0,774},{9,0,776},{9,0,784},{10,0,567},{10,0,708},{11,0, +518},{11,0,613},{11,0,695},{11,0,716},{11,0,739},{11,0,770},{11,0,771},{11,0,848 +},{11,0,857},{11,0,931},{11,0,947},{12,0,326},{12,0,387},{12,0,484},{12,0,528},{ +12,0,552},{12,0,613},{13,0,189},{13,0,256},{13,0,340},{13,0,432},{13,0,436},{13, +0,440},{13,0,454},{14,0,174},{14,0,220},{14,0,284},{14,0,390},{145,0,121},{135, +10,158},{9,0,137},{138,0,221},{4,11,110},{10,11,415},{10,11,597},{142,11,206},{ +141,11,496},{135,11,205},{151,10,25},{135,11,778},{7,10,2001},{7,11,1656},{9,11, +369},{10,11,338},{10,11,490},{11,11,154},{11,11,545},{11,11,775},{13,11,77},{141 +,11,274},{4,11,444},{10,11,146},{140,11,9},{7,0,390},{138,0,140},{135,0,1144},{ +134,0,464},{7,10,1461},{140,10,91},{132,10,602},{4,11,283},{135,11,1194},{5,0, +407},{11,0,204},{11,0,243},{11,0,489},{12,0,293},{19,0,37},{20,0,73},{150,0,38}, +{7,0,1218},{136,0,303},{4,10,13},{5,0,325},{5,10,567},{7,10,1498},{8,0,5},{8,0, +227},{9,0,105},{9,10,124},{10,0,585},{11,10,521},{12,0,614},{140,10,405},{135,10 +,1006},{6,11,1720},{7,0,800},{138,0,12},{135,0,1783},{132,10,735},{138,10,812},{ +4,10,170},{135,10,323},{6,0,621},{13,0,504},{144,0,89},{5,10,304},{135,10,1403}, +{137,11,216},{6,0,920},{6,0,1104},{9,11,183},{139,11,286},{4,0,376},{133,10,742} +,{134,0,218},{8,0,641},{11,0,388},{140,0,580},{7,0,454},{7,0,782},{8,0,768},{140 +,0,686},{137,11,33},{133,10,111},{144,0,0},{10,0,676},{140,0,462},{6,0,164},{136 +,11,735},{133,10,444},{150,0,50},{7,11,1862},{12,11,491},{12,11,520},{13,11,383} +,{14,11,244},{146,11,12},{5,11,132},{9,11,486},{9,11,715},{10,11,458},{11,11,373 +},{11,11,668},{11,11,795},{11,11,897},{12,11,272},{12,11,424},{12,11,539},{12,11 +,558},{14,11,245},{14,11,263},{14,11,264},{14,11,393},{142,11,403},{8,10,123},{ +15,10,6},{144,10,7},{6,0,285},{8,0,654},{11,0,749},{12,0,190},{12,0,327},{13,0, +120},{13,0,121},{13,0,327},{15,0,47},{146,0,40},{5,11,8},{6,11,89},{6,11,400},{7 +,11,1569},{7,11,1623},{7,11,1850},{8,11,218},{8,11,422},{9,11,570},{138,11,626}, +{6,11,387},{7,11,882},{141,11,111},{6,0,343},{6,11,224},{7,0,195},{7,11,877},{9, +0,226},{9,11,647},{10,0,197},{10,0,575},{11,0,502},{139,0,899},{5,10,937},{135, +10,100},{135,11,790},{150,0,29},{147,0,8},{134,0,1812},{149,0,8},{135,11,394},{7 +,0,1125},{9,0,143},{11,0,61},{14,0,405},{150,0,21},{10,11,755},{147,11,29},{9,11 +,378},{141,11,162},{135,10,922},{5,10,619},{133,10,698},{134,0,1327},{6,0,1598}, +{137,0,575},{9,11,569},{12,11,12},{12,11,81},{12,11,319},{13,11,69},{14,11,259}, +{16,11,87},{17,11,1},{17,11,21},{17,11,24},{18,11,15},{18,11,56},{18,11,59},{18, +11,127},{18,11,154},{19,11,19},{148,11,31},{6,0,895},{135,11,1231},{5,0,959},{7, +11,124},{136,11,38},{5,11,261},{7,11,78},{7,11,199},{8,11,815},{9,11,126},{138, +11,342},{5,10,917},{134,10,1659},{5,11,595},{7,0,1759},{135,11,1863},{136,0,173} +,{134,0,266},{142,0,261},{132,11,628},{5,10,251},{5,10,956},{8,10,268},{9,10,214 +},{146,10,142},{7,11,266},{136,11,804},{135,11,208},{6,11,79},{7,11,1021},{135, +11,1519},{11,11,704},{141,11,396},{5,10,346},{5,10,711},{136,10,390},{136,11,741 +},{134,11,376},{134,0,1427},{6,0,1033},{6,0,1217},{136,0,300},{133,10,624},{6,11 +,100},{7,11,244},{7,11,632},{7,11,1609},{8,11,178},{8,11,638},{141,11,58},{5,10, +783},{6,0,584},{7,10,1998},{135,10,2047},{5,0,427},{5,0,734},{7,0,478},{136,0,52 +},{7,0,239},{11,0,217},{142,0,165},{134,0,1129},{6,0,168},{6,0,1734},{7,0,20},{7 +,0,1056},{8,0,732},{9,0,406},{9,0,911},{138,0,694},{132,10,594},{133,11,791},{7, +11,686},{8,11,33},{8,11,238},{10,11,616},{11,11,467},{11,11,881},{13,11,217},{13 +,11,253},{142,11,268},{137,11,476},{134,0,418},{133,0,613},{132,0,632},{132,11, +447},{7,0,32},{7,0,984},{8,0,85},{8,0,709},{9,0,579},{9,0,847},{9,0,856},{10,0, +799},{11,0,258},{11,0,1007},{12,0,331},{12,0,615},{13,0,188},{13,0,435},{14,0,8} +,{15,0,165},{16,0,27},{16,11,35},{148,0,40},{4,11,128},{5,11,415},{6,11,462},{7, +11,294},{7,11,578},{10,11,710},{139,11,86},{5,0,694},{136,0,909},{5,10,37},{6,10 +,39},{6,10,451},{7,0,1109},{7,10,218},{7,10,1166},{7,10,1687},{8,10,662},{11,0,7 +},{144,10,2},{136,11,587},{6,11,427},{7,11,1018},{138,11,692},{4,11,195},{6,10, +508},{135,11,802},{4,0,167},{135,0,82},{5,0,62},{6,0,24},{6,0,534},{7,0,74},{7,0 +,678},{7,0,684},{7,0,1043},{7,0,1072},{8,0,280},{8,0,541},{8,0,686},{9,0,258},{ +10,0,519},{11,0,252},{140,0,282},{138,0,33},{4,0,359},{133,11,738},{7,0,980},{7, +10,635},{7,10,796},{8,10,331},{9,0,328},{9,10,330},{9,10,865},{10,10,119},{10,10 +,235},{11,10,111},{11,10,129},{11,10,240},{12,10,31},{12,10,66},{12,10,222},{12, +10,269},{12,10,599},{12,10,684},{12,10,689},{12,10,691},{13,0,186},{13,0,364},{ +142,10,345},{137,10,527},{6,0,596},{7,0,585},{135,10,702},{134,11,1683},{133,0, +211},{6,0,145},{141,0,336},{134,0,1130},{6,10,37},{7,0,873},{7,10,1666},{8,10, +195},{8,10,316},{9,10,178},{9,10,276},{9,10,339},{9,10,536},{10,10,102},{10,10, +362},{10,10,785},{11,10,55},{11,10,149},{11,10,773},{13,10,416},{13,10,419},{14, +10,38},{14,10,41},{142,10,210},{8,0,840},{136,0,841},{132,0,263},{5,11,3},{8,11, +578},{9,11,118},{10,11,705},{12,11,383},{141,11,279},{132,0,916},{133,11,229},{ +133,10,645},{8,11,102},{10,11,578},{10,11,672},{12,11,496},{13,11,408},{14,11, +121},{15,0,155},{16,0,79},{145,11,106},{4,0,599},{5,0,592},{6,0,1634},{7,0,5},{7 +,0,55},{7,0,67},{7,0,97},{7,0,691},{7,0,979},{7,0,1600},{7,0,1697},{8,0,207},{8, +0,214},{8,0,231},{8,0,294},{8,0,336},{8,0,428},{8,0,471},{8,0,622},{8,0,626},{8, +0,679},{8,0,759},{8,0,829},{9,0,11},{9,0,246},{9,0,484},{9,0,573},{9,0,706},{9,0 +,762},{9,0,798},{9,0,855},{9,0,870},{9,0,912},{10,0,303},{10,0,335},{10,0,424},{ +10,0,461},{10,0,543},{10,0,759},{10,0,814},{11,0,59},{11,0,199},{11,0,235},{11,0 +,590},{11,0,631},{11,0,929},{11,0,963},{11,0,987},{12,0,114},{12,0,182},{12,0, +226},{12,0,332},{12,0,439},{12,0,575},{12,0,598},{12,0,675},{13,0,8},{13,0,125}, +{13,0,194},{13,0,287},{14,0,197},{14,0,383},{15,0,53},{17,0,63},{19,0,46},{19,0, +98},{19,0,106},{148,0,85},{4,10,290},{135,0,1356},{6,10,70},{7,10,1292},{10,10, +762},{139,10,288},{150,11,55},{4,0,593},{8,11,115},{8,11,350},{9,11,489},{10,11, +128},{11,11,306},{12,11,373},{14,11,30},{17,11,79},{147,11,80},{135,11,1235},{ +134,0,1392},{4,11,230},{133,11,702},{147,0,126},{7,10,131},{7,10,422},{8,10,210} +,{140,10,573},{134,0,1179},{139,11,435},{139,10,797},{134,11,1728},{4,0,162},{18 +,11,26},{19,11,42},{20,11,43},{21,11,0},{23,11,27},{152,11,14},{132,10,936},{5, +10,453},{6,0,765},{134,10,441},{133,0,187},{135,0,1286},{6,0,635},{6,0,904},{6,0 +,1210},{134,0,1489},{4,0,215},{8,0,890},{9,0,38},{10,0,923},{11,0,23},{11,0,127} +,{139,0,796},{6,0,1165},{134,0,1306},{7,0,716},{13,0,97},{141,0,251},{132,10,653 +},{136,0,657},{146,10,80},{5,11,622},{7,11,1032},{11,11,26},{11,11,213},{11,11, +707},{12,11,380},{13,11,226},{141,11,355},{5,11,70},{6,0,299},{6,11,334},{9,11, +171},{11,11,637},{12,11,202},{14,11,222},{145,11,42},{142,0,134},{4,11,23},{5,11 +,313},{5,11,1014},{6,11,50},{6,11,51},{7,11,142},{7,11,384},{9,11,783},{139,11, +741},{4,11,141},{7,11,559},{8,11,640},{9,11,460},{12,11,183},{141,11,488},{136, +11,614},{7,10,1368},{8,10,232},{8,10,361},{10,10,682},{138,10,742},{137,10,534}, +{6,0,1082},{140,0,658},{137,10,27},{135,0,2002},{142,10,12},{4,0,28},{5,0,440},{ +7,0,248},{11,0,833},{140,0,344},{7,10,736},{139,10,264},{134,10,1657},{134,0, +1654},{138,0,531},{5,11,222},{9,11,140},{138,11,534},{6,0,634},{6,0,798},{134,0, +840},{138,11,503},{135,10,127},{133,0,853},{5,11,154},{7,11,1491},{10,11,379},{ +138,11,485},{6,0,249},{7,0,1234},{139,0,573},{133,11,716},{7,11,1570},{140,11, +542},{136,10,364},{138,0,527},{4,11,91},{5,11,388},{5,11,845},{6,11,206},{6,11, +252},{6,11,365},{7,11,136},{7,11,531},{8,11,264},{136,11,621},{134,0,1419},{135, +11,1441},{7,0,49},{7,0,392},{8,0,20},{8,0,172},{8,0,690},{9,0,383},{9,0,845},{10 +,0,48},{11,0,293},{11,0,832},{11,0,920},{11,0,984},{141,0,221},{5,0,858},{133,0, +992},{5,0,728},{137,10,792},{5,10,909},{9,10,849},{138,10,805},{7,0,525},{7,0, +1579},{8,0,497},{136,0,573},{6,0,268},{137,0,62},{135,11,576},{134,0,1201},{5,11 +,771},{5,11,863},{5,11,898},{6,11,1632},{6,11,1644},{134,11,1780},{133,11,331},{ +7,0,193},{7,0,1105},{7,10,397},{8,10,124},{8,10,619},{9,10,305},{10,0,495},{11, +10,40},{12,10,349},{13,10,134},{13,10,295},{14,10,155},{15,10,120},{146,10,105}, +{138,0,106},{5,11,107},{6,0,859},{7,11,201},{136,11,518},{6,11,446},{135,11,1817 +},{4,10,262},{7,10,342},{141,0,23},{133,10,641},{137,11,851},{6,0,925},{137,0, +813},{132,11,504},{6,0,613},{136,0,223},{4,10,99},{6,10,250},{6,10,346},{8,10, +127},{138,10,81},{136,0,953},{132,10,915},{139,11,892},{5,10,75},{9,10,517},{10, +10,470},{12,10,155},{141,10,224},{4,0,666},{7,0,1017},{7,11,996},{138,11,390},{5 +,11,883},{133,11,975},{14,10,83},{142,11,83},{4,0,670},{5,11,922},{134,11,1707}, +{135,0,216},{7,11,787},{9,0,40},{139,0,136},{5,10,954},{5,11,993},{7,11,515},{ +137,11,91},{139,0,259},{6,10,304},{7,0,1114},{8,10,418},{9,0,310},{9,0,682},{10, +0,440},{11,10,341},{11,10,675},{141,0,40},{9,10,410},{11,10,425},{142,0,296},{10 +,11,377},{12,11,363},{13,11,68},{13,11,94},{14,11,108},{142,11,306},{7,0,1401},{ +135,0,1476},{4,0,296},{6,0,475},{7,0,401},{7,0,1410},{7,0,1594},{7,0,1674},{8,0, +63},{8,0,660},{137,0,74},{4,0,139},{4,0,388},{140,0,188},{132,0,797},{132,11,766 +},{5,11,103},{7,11,921},{8,11,580},{8,11,593},{8,11,630},{138,11,28},{4,11,911}, +{5,11,867},{133,11,1013},{134,10,14},{134,0,1572},{134,10,1708},{5,10,113},{6,10 +,243},{7,10,1865},{11,10,161},{16,10,37},{17,10,99},{149,0,39},{7,11,1563},{141, +11,182},{5,11,135},{6,11,519},{7,11,1722},{10,11,271},{11,11,261},{145,11,54},{ +132,10,274},{134,0,1594},{4,11,300},{5,11,436},{135,11,484},{4,0,747},{6,0,290}, +{7,0,649},{7,0,1479},{135,0,1583},{133,11,535},{147,11,82},{133,0,232},{137,0, +887},{135,10,166},{136,0,521},{4,0,14},{7,0,472},{7,0,1801},{10,0,748},{141,0, +458},{134,0,741},{134,0,992},{9,10,304},{144,0,111},{4,0,425},{5,11,387},{7,11, +557},{12,11,547},{142,11,86},{135,11,1747},{5,10,654},{135,11,1489},{4,11,6},{5, +11,708},{7,0,789},{136,11,75},{6,10,273},{10,10,188},{13,10,377},{146,10,77},{4, +11,303},{6,0,1593},{7,11,619},{10,11,547},{10,11,687},{11,11,122},{140,11,601},{ +134,0,1768},{135,10,410},{138,11,772},{11,0,233},{139,10,524},{5,0,943},{134,0, +1779},{134,10,1785},{136,11,529},{132,0,955},{5,0,245},{6,0,576},{7,0,582},{136, +0,225},{132,10,780},{142,0,241},{134,0,1943},{4,11,106},{7,11,310},{7,11,1785},{ +10,11,690},{139,11,717},{134,0,1284},{5,11,890},{133,11,988},{6,11,626},{142,11, +431},{10,11,706},{145,11,32},{137,11,332},{132,11,698},{135,0,709},{5,10,948},{ +138,11,17},{136,0,554},{134,0,1564},{139,10,941},{132,0,443},{134,0,909},{134,11 +,84},{142,0,280},{4,10,532},{5,10,706},{135,10,662},{132,0,729},{5,10,837},{6,10 +,1651},{139,10,985},{135,10,1861},{4,0,348},{152,11,3},{5,11,986},{6,11,130},{7, +11,1582},{8,11,458},{10,11,101},{10,11,318},{138,11,823},{134,0,758},{4,0,298},{ +137,0,848},{4,10,330},{7,10,933},{7,10,2012},{136,10,292},{7,11,1644},{137,11, +129},{6,0,1422},{7,10,767},{137,0,829},{5,0,164},{7,0,121},{142,0,189},{7,0,812} +,{7,0,1261},{7,0,1360},{9,0,632},{140,0,352},{135,11,1788},{139,0,556},{135,11, +997},{145,10,114},{4,0,172},{9,0,611},{9,10,883},{10,0,436},{12,0,673},{141,0, +255},{10,10,274},{139,0,530},{133,0,844},{134,0,984},{4,10,703},{7,10,207},{13,0 +,232},{146,0,35},{132,10,571},{9,0,263},{10,0,147},{138,0,492},{7,11,1756},{137, +11,98},{5,10,873},{5,10,960},{8,10,823},{137,10,881},{133,0,537},{132,0,859},{7, +11,1046},{139,11,160},{137,0,842},{139,10,283},{5,10,33},{6,10,470},{139,10,424} +,{6,11,45},{7,11,433},{8,11,129},{9,11,21},{10,11,392},{11,11,79},{12,11,499},{ +13,11,199},{141,11,451},{135,0,1291},{135,10,1882},{7,11,558},{136,11,353},{134, +0,1482},{5,0,230},{5,0,392},{6,0,420},{9,0,568},{140,0,612},{6,0,262},{7,10,90}, +{7,10,664},{7,10,830},{7,10,1380},{7,10,2025},{8,10,448},{8,10,828},{8,11,81},{9 +,11,189},{9,11,201},{11,11,478},{11,11,712},{141,11,338},{142,0,31},{5,11,353},{ +151,11,26},{132,0,753},{4,0,0},{5,0,41},{7,0,1459},{7,0,1469},{7,0,1859},{9,0, +549},{139,0,905},{9,10,417},{137,10,493},{135,11,1113},{133,0,696},{141,11,448}, +{134,10,295},{132,0,834},{4,0,771},{5,10,1019},{6,11,25},{7,11,855},{7,11,1258}, +{144,11,32},{134,0,1076},{133,0,921},{133,0,674},{4,11,4},{7,11,1118},{7,11,1320 +},{7,11,1706},{8,11,277},{9,11,622},{10,11,9},{11,11,724},{12,11,350},{12,11,397 +},{13,11,28},{13,11,159},{15,11,89},{18,11,5},{19,11,9},{20,11,34},{150,11,47},{ +134,10,208},{6,0,444},{136,0,308},{6,0,180},{7,0,1137},{8,0,751},{139,0,805},{4, +0,183},{7,0,271},{11,0,824},{11,0,952},{13,0,278},{13,0,339},{13,0,482},{14,0, +424},{148,0,99},{7,11,317},{135,11,569},{4,0,19},{5,0,477},{5,0,596},{6,0,505},{ +7,0,1221},{11,0,907},{12,0,209},{141,0,214},{135,0,1215},{6,0,271},{7,0,398},{7, +10,448},{7,10,1629},{7,10,1813},{8,0,387},{8,10,442},{9,10,710},{10,0,344},{10, +10,282},{138,10,722},{11,10,844},{12,10,104},{140,10,625},{134,11,255},{133,10, +787},{134,0,1645},{11,11,956},{151,11,3},{6,0,92},{6,0,188},{7,0,209},{7,0,1269} +,{7,0,1524},{7,0,1876},{8,0,661},{10,0,42},{10,0,228},{11,0,58},{11,0,1020},{12, +0,58},{12,0,118},{141,0,32},{4,0,459},{133,0,966},{4,11,536},{7,11,1141},{10,11, +723},{139,11,371},{140,0,330},{134,0,1557},{7,11,285},{135,11,876},{136,10,491}, +{135,11,560},{6,0,18},{7,0,179},{7,0,932},{8,0,548},{8,0,757},{9,0,54},{9,0,65}, +{9,0,532},{9,0,844},{10,0,113},{10,0,117},{10,0,315},{10,0,560},{10,0,622},{10,0 +,798},{11,0,153},{11,0,351},{11,0,375},{12,0,78},{12,0,151},{12,0,392},{12,0,666 +},{14,0,248},{143,0,23},{4,11,690},{134,0,1742},{4,10,403},{5,10,441},{7,10,450} +,{10,10,840},{11,10,101},{12,10,193},{141,10,430},{133,0,965},{134,0,182},{10,0, +65},{10,0,488},{138,0,497},{135,11,1346},{6,0,973},{6,0,1158},{10,11,200},{19,11 +,2},{151,11,22},{4,11,190},{133,11,554},{133,10,679},{7,0,328},{137,10,326},{133 +,11,1001},{9,0,588},{138,0,260},{133,11,446},{135,10,1128},{135,10,1796},{147,11 +,119},{134,0,1786},{6,0,1328},{6,0,1985},{8,0,962},{138,0,1017},{135,0,308},{4, +10,574},{7,10,350},{7,10,1024},{8,10,338},{9,10,677},{10,10,808},{139,0,508},{ +138,11,752},{135,10,1081},{137,11,96},{7,10,1676},{135,10,2037},{136,0,588},{132 +,11,304},{133,0,614},{140,0,793},{136,0,287},{137,10,297},{141,10,37},{6,11,53}, +{6,11,199},{7,11,1408},{8,11,32},{8,11,93},{9,11,437},{10,11,397},{10,11,629},{ +11,11,593},{11,11,763},{13,11,326},{145,11,35},{134,11,105},{9,11,320},{10,11, +506},{138,11,794},{5,11,114},{5,11,255},{141,11,285},{140,0,290},{7,11,2035},{8, +11,19},{9,11,89},{138,11,831},{134,0,1136},{6,10,306},{7,0,719},{7,10,1140},{7, +10,1340},{8,0,796},{8,0,809},{8,0,834},{8,10,133},{138,10,449},{139,10,1011},{5, +0,210},{6,0,213},{7,0,60},{10,0,364},{139,0,135},{5,0,607},{8,0,326},{136,0,490} +,{138,11,176},{132,0,701},{5,0,472},{7,0,380},{137,0,758},{135,0,1947},{6,0,1079 +},{138,0,278},{138,11,391},{5,10,329},{8,10,260},{139,11,156},{4,0,386},{7,0,41} +,{8,0,405},{8,0,728},{9,0,497},{11,0,110},{11,0,360},{15,0,37},{144,0,84},{5,0, +46},{7,0,1452},{7,0,1480},{8,0,634},{140,0,472},{136,0,961},{4,0,524},{136,0,810 +},{10,0,238},{141,0,33},{132,10,657},{152,10,7},{133,0,532},{5,0,997},{135,10, +1665},{7,11,594},{7,11,851},{7,11,1858},{9,11,411},{9,11,574},{9,11,666},{9,11, +737},{10,11,346},{10,11,712},{11,11,246},{11,11,432},{11,11,517},{11,11,647},{11 +,11,679},{11,11,727},{12,11,304},{12,11,305},{12,11,323},{12,11,483},{12,11,572} +,{12,11,593},{12,11,602},{13,11,95},{13,11,101},{13,11,171},{13,11,315},{13,11, +378},{13,11,425},{13,11,475},{14,11,63},{14,11,380},{14,11,384},{15,11,133},{18, +11,112},{148,11,72},{5,11,955},{136,11,814},{134,0,1301},{5,10,66},{7,10,1896},{ +136,10,288},{133,11,56},{134,10,1643},{6,0,1298},{148,11,100},{5,0,782},{5,0,829 +},{6,0,671},{6,0,1156},{6,0,1738},{137,11,621},{4,0,306},{5,0,570},{5,10,91},{5, +10,648},{5,10,750},{5,10,781},{6,10,54},{6,10,112},{6,10,402},{6,10,1732},{7,0, +1347},{7,10,315},{7,10,749},{7,10,1900},{9,10,78},{9,10,508},{10,10,611},{10,10, +811},{11,10,510},{11,10,728},{13,10,36},{14,10,39},{16,10,83},{17,10,124},{148, +10,30},{8,10,570},{9,11,477},{141,11,78},{4,11,639},{10,10,322},{10,10,719},{10, +11,4},{11,10,407},{11,11,638},{12,11,177},{148,11,57},{7,0,1823},{139,0,693},{5, +11,758},{7,0,759},{8,10,125},{8,10,369},{8,10,524},{10,10,486},{11,10,13},{11,10 +,381},{11,10,736},{11,10,766},{11,10,845},{13,10,114},{13,10,292},{142,10,47},{6 +,10,1684},{6,10,1731},{7,0,1932},{7,10,356},{8,10,54},{8,10,221},{9,10,225},{9, +10,356},{10,10,77},{10,10,446},{10,10,731},{12,10,404},{141,10,491},{135,11,552} +,{135,11,1112},{4,0,78},{5,0,96},{5,0,182},{6,0,1257},{7,0,1724},{7,0,1825},{10, +0,394},{10,0,471},{11,0,532},{14,0,340},{145,0,88},{139,11,328},{135,0,1964},{ +132,10,411},{4,10,80},{5,10,44},{137,11,133},{5,11,110},{6,11,169},{6,11,1702},{ +7,11,400},{8,11,538},{9,11,184},{9,11,524},{140,11,218},{4,0,521},{5,10,299},{7, +10,1083},{140,11,554},{6,11,133},{9,11,353},{12,11,628},{146,11,79},{6,0,215},{7 +,0,584},{7,0,1028},{7,0,1473},{7,0,1721},{9,0,424},{138,0,779},{7,0,857},{7,0, +1209},{7,10,1713},{9,10,537},{10,10,165},{12,10,219},{140,10,561},{4,10,219},{6, +11,93},{7,10,1761},{7,11,1422},{7,11,1851},{8,11,673},{9,10,86},{9,11,529},{140, +11,43},{137,11,371},{136,0,671},{5,0,328},{135,0,918},{132,0,529},{9,11,25},{10, +11,467},{138,11,559},{4,11,335},{135,11,942},{134,0,716},{134,0,1509},{6,0,67},{ +7,0,258},{7,0,1630},{9,0,354},{9,0,675},{10,0,830},{12,10,428},{14,0,80},{145,0, +80},{134,0,1112},{6,0,141},{7,0,225},{9,0,59},{9,0,607},{10,0,312},{11,0,687},{ +12,0,555},{13,0,373},{13,0,494},{148,0,58},{133,10,514},{8,11,39},{10,11,773},{ +11,11,84},{12,11,205},{142,11,1},{5,11,601},{5,11,870},{136,0,783},{136,11,594}, +{4,10,55},{5,10,301},{6,10,571},{14,10,49},{146,10,102},{132,11,181},{134,11, +1652},{133,10,364},{4,11,97},{5,11,147},{6,11,286},{7,11,1362},{141,11,176},{4, +10,76},{7,10,1550},{9,10,306},{9,10,430},{9,10,663},{10,10,683},{11,10,427},{11, +10,753},{12,10,334},{12,10,442},{14,10,258},{14,10,366},{143,10,131},{137,10,52} +,{6,0,955},{134,0,1498},{6,11,375},{7,11,169},{7,11,254},{136,11,780},{7,0,430}, +{11,0,46},{14,0,343},{142,11,343},{135,0,1183},{5,0,602},{7,0,2018},{7,11,1447}, +{9,0,418},{137,0,803},{7,11,1044},{136,0,677},{139,11,285},{4,10,656},{135,10, +779},{135,10,144},{5,11,629},{135,11,1549},{135,10,1373},{138,11,209},{7,10,554} +,{7,10,605},{141,10,10},{5,10,838},{5,10,841},{134,10,1649},{133,10,1012},{6,0, +1357},{134,0,1380},{144,0,53},{6,0,590},{7,10,365},{7,10,1357},{7,10,1497},{8,10 +,154},{141,10,281},{133,10,340},{132,11,420},{135,0,329},{147,11,32},{4,0,469},{ +10,11,429},{139,10,495},{8,10,261},{9,10,144},{9,10,466},{10,10,370},{12,10,470} +,{13,10,144},{142,10,348},{142,0,460},{4,11,325},{9,10,897},{138,11,125},{6,0, +1743},{6,10,248},{9,10,546},{10,10,535},{11,10,681},{141,10,135},{4,0,990},{5,0, +929},{6,0,340},{8,0,376},{8,0,807},{8,0,963},{8,0,980},{138,0,1007},{134,0,1603} +,{140,0,250},{4,11,714},{133,11,469},{134,10,567},{136,10,445},{5,0,218},{7,0, +1610},{8,0,646},{10,0,83},{11,11,138},{140,11,40},{7,0,1512},{135,0,1794},{135, +11,1216},{4,11,718},{11,0,0},{144,0,78},{133,0,571},{132,0,455},{134,0,1012},{5, +11,124},{5,11,144},{6,11,548},{7,11,15},{7,11,153},{137,11,629},{142,11,10},{6, +11,75},{7,11,1531},{8,11,416},{9,11,240},{9,11,275},{10,11,100},{11,11,658},{11, +11,979},{12,11,86},{13,11,468},{14,11,66},{14,11,207},{15,11,20},{15,11,25},{144 +,11,58},{132,10,577},{5,11,141},{5,11,915},{6,11,1783},{7,11,211},{7,11,698},{7, +11,1353},{9,11,83},{9,11,281},{10,11,376},{10,11,431},{11,11,543},{12,11,664},{ +13,11,280},{13,11,428},{14,11,61},{14,11,128},{17,11,52},{145,11,81},{6,0,161},{ +7,0,372},{137,0,597},{132,0,349},{10,11,702},{139,11,245},{134,0,524},{134,10, +174},{6,0,432},{9,0,751},{139,0,322},{147,11,94},{4,11,338},{133,11,400},{5,0, +468},{10,0,325},{11,0,856},{12,0,345},{143,0,104},{133,0,223},{132,0,566},{4,11, +221},{5,11,659},{5,11,989},{7,11,697},{7,11,1211},{138,11,284},{135,11,1070},{4, +0,59},{135,0,1394},{5,10,878},{5,10,972},{6,0,436},{139,0,481},{4,0,48},{5,0,271 +},{135,0,953},{5,0,610},{136,0,457},{4,0,773},{5,0,618},{137,0,756},{133,0,755}, +{135,0,1217},{138,11,507},{132,10,351},{132,0,197},{143,11,78},{4,11,188},{7,11, +805},{11,11,276},{142,11,293},{5,11,884},{139,11,991},{132,10,286},{7,10,438},{7 +,10,627},{7,10,1516},{8,10,40},{9,10,56},{9,10,294},{10,0,259},{10,0,428},{11,10 +,969},{11,10,995},{146,10,148},{4,0,356},{5,0,217},{5,0,492},{5,0,656},{8,0,544} +,{136,11,544},{5,0,259},{6,0,1230},{7,0,414},{7,0,854},{142,0,107},{132,0,1007}, +{15,0,14},{144,0,5},{4,10,738},{134,0,1580},{132,11,596},{132,0,673},{133,10,866 +},{6,0,1843},{135,11,1847},{4,0,165},{7,0,1398},{135,0,1829},{135,11,1634},{147, +11,65},{6,0,885},{6,0,1009},{137,0,809},{133,10,116},{132,10,457},{136,11,770},{ +9,0,498},{10,11,361},{12,0,181},{142,11,316},{134,11,595},{5,0,9},{7,0,297},{7,0 +,966},{140,0,306},{4,11,89},{5,11,489},{6,11,315},{7,11,553},{7,11,1745},{138,11 +,243},{134,0,1487},{132,0,437},{5,0,146},{6,0,411},{138,0,721},{5,10,527},{6,10, +189},{135,10,859},{11,10,104},{11,10,554},{15,10,60},{143,10,125},{6,11,1658},{9 +,11,3},{10,11,154},{11,11,641},{13,11,85},{13,11,201},{141,11,346},{6,0,177},{ +135,0,467},{134,0,1377},{134,10,116},{136,11,645},{4,11,166},{5,11,505},{6,11, +1670},{137,11,110},{133,10,487},{4,10,86},{5,10,667},{5,10,753},{6,10,316},{6,10 +,455},{135,10,946},{133,0,200},{132,0,959},{6,0,1928},{134,0,1957},{139,11,203}, +{150,10,45},{4,10,79},{7,10,1773},{10,10,450},{11,10,589},{13,10,332},{13,10,493 +},{14,10,183},{14,10,334},{14,10,362},{14,10,368},{14,10,376},{14,10,379},{19,10 +,90},{19,10,103},{19,10,127},{148,10,90},{6,0,1435},{135,11,1275},{134,0,481},{7 +,11,445},{8,11,307},{8,11,704},{10,11,41},{10,11,439},{11,11,237},{11,11,622},{ +140,11,201},{135,11,869},{4,0,84},{7,0,1482},{10,0,76},{138,0,142},{11,11,277},{ +144,11,14},{135,11,1977},{4,11,189},{5,11,713},{136,11,57},{133,0,1015},{138,11, +371},{4,0,315},{5,0,507},{135,0,1370},{4,11,552},{142,10,381},{9,0,759},{16,0,31 +},{16,0,39},{16,0,75},{18,0,24},{20,0,42},{152,0,1},{134,0,712},{134,0,1722},{ +133,10,663},{133,10,846},{8,0,222},{8,0,476},{9,0,238},{11,0,516},{11,0,575},{15 +,0,109},{146,0,100},{5,10,378},{7,0,1402},{7,0,1414},{8,10,465},{9,10,286},{10, +10,185},{10,10,562},{10,10,635},{11,10,31},{11,10,393},{12,0,456},{13,10,312},{ +18,10,65},{18,10,96},{147,10,89},{4,0,986},{6,0,1958},{6,0,2032},{8,0,934},{138, +0,985},{7,10,1880},{9,10,680},{139,10,798},{134,10,1770},{145,11,49},{132,11,614 +},{132,10,648},{5,10,945},{6,10,1656},{6,10,1787},{7,10,167},{8,10,824},{9,10, +391},{10,10,375},{139,10,185},{138,11,661},{7,0,1273},{135,11,1945},{7,0,706},{7 +,0,1058},{138,0,538},{7,10,1645},{8,10,352},{137,10,249},{132,10,152},{11,0,92}, +{11,0,196},{11,0,409},{11,0,450},{11,0,666},{11,0,777},{12,0,262},{13,0,385},{13 +,0,393},{15,0,115},{16,0,45},{145,0,82},{133,10,1006},{6,0,40},{135,0,1781},{9, +11,614},{139,11,327},{5,10,420},{135,10,1449},{135,0,431},{7,10,832},{138,0,97}, +{6,0,423},{7,0,665},{135,0,1210},{7,0,237},{8,0,664},{9,0,42},{9,0,266},{9,0,380 +},{9,0,645},{10,0,177},{138,0,276},{5,10,351},{135,0,264},{5,10,40},{7,10,598},{ +7,10,1638},{8,0,213},{9,10,166},{9,10,640},{9,10,685},{9,10,773},{11,10,215},{13 +,10,65},{14,10,172},{14,10,317},{145,10,6},{5,11,84},{134,11,163},{8,10,60},{9, +10,343},{139,10,769},{137,0,455},{133,11,410},{8,0,906},{12,0,700},{12,0,706},{ +140,0,729},{21,11,33},{150,11,40},{7,10,1951},{8,10,765},{8,10,772},{140,10,671} +,{7,10,108},{8,10,219},{8,10,388},{9,10,639},{9,10,775},{11,10,275},{140,10,464} +,{5,11,322},{7,11,1941},{8,11,186},{9,11,262},{10,11,187},{14,11,208},{146,11, +130},{139,0,624},{5,11,227},{8,0,574},{140,11,29},{7,11,1546},{11,11,299},{142, +11,407},{5,10,15},{6,10,56},{7,10,1758},{8,10,500},{9,10,730},{11,10,331},{13,10 +,150},{142,10,282},{7,11,1395},{8,11,486},{9,11,236},{9,11,878},{10,11,218},{11, +11,95},{19,11,17},{147,11,31},{135,11,2043},{4,0,354},{146,11,4},{140,11,80},{ +135,0,1558},{134,10,1886},{5,10,205},{6,10,438},{137,10,711},{133,11,522},{133, +10,534},{7,0,235},{7,0,1475},{15,0,68},{146,0,120},{137,10,691},{4,0,942},{6,0, +1813},{8,0,917},{10,0,884},{12,0,696},{12,0,717},{12,0,723},{12,0,738},{12,0,749 +},{12,0,780},{16,0,97},{146,0,169},{6,10,443},{8,11,562},{9,10,237},{9,10,571},{ +9,10,695},{10,10,139},{11,10,715},{12,10,417},{141,10,421},{135,0,957},{133,0, +830},{134,11,1771},{146,0,23},{5,0,496},{6,0,694},{7,0,203},{7,11,1190},{137,11, +620},{137,11,132},{6,0,547},{134,0,1549},{8,11,258},{9,11,208},{137,11,359},{4,0 +,864},{5,0,88},{137,0,239},{135,11,493},{4,11,317},{135,11,1279},{132,11,477},{4 +,10,578},{5,11,63},{133,11,509},{7,0,650},{135,0,1310},{7,0,1076},{9,0,80},{11,0 +,78},{11,0,421},{11,0,534},{140,0,545},{132,11,288},{5,10,923},{12,0,553},{142,0 +,118},{7,0,274},{11,0,479},{139,0,507},{8,11,89},{8,11,620},{9,11,49},{10,11,774 +},{11,11,628},{12,11,322},{143,11,124},{4,0,497},{135,0,1584},{4,10,924},{7,0, +261},{7,0,1115},{7,0,1354},{7,0,1404},{7,0,1588},{7,0,1705},{7,0,1902},{9,0,465} +,{10,0,248},{10,0,349},{10,0,647},{11,0,527},{11,0,660},{11,0,669},{12,0,529},{ +141,0,305},{133,10,665},{136,0,13},{6,0,791},{138,11,120},{7,0,642},{8,0,250},{ +11,0,123},{11,0,137},{13,0,48},{142,0,95},{4,10,265},{7,10,807},{135,10,950},{5, +10,93},{140,10,267},{135,0,1429},{4,0,949},{10,0,885},{10,0,891},{10,0,900},{10, +0,939},{12,0,760},{142,0,449},{139,11,366},{132,0,818},{134,11,85},{135,10,994}, +{5,10,233},{5,10,320},{6,10,140},{7,0,330},{136,10,295},{4,0,1004},{8,0,982},{ +136,0,993},{133,10,978},{4,10,905},{6,10,1701},{137,10,843},{10,0,545},{140,0, +301},{6,0,947},{134,0,1062},{134,0,1188},{4,0,904},{5,0,794},{152,10,6},{134,0, +1372},{135,11,608},{5,11,279},{6,11,235},{7,11,468},{8,11,446},{9,11,637},{10,11 +,717},{11,11,738},{140,11,514},{132,10,509},{5,11,17},{6,11,371},{137,11,528},{ +132,0,693},{4,11,115},{5,11,669},{6,11,407},{8,11,311},{11,11,10},{141,11,5},{7, +10,273},{9,11,381},{139,0,377},{135,0,695},{7,0,386},{138,0,713},{135,10,1041},{ +134,0,1291},{6,0,7},{6,0,35},{7,0,147},{7,0,1069},{7,0,1568},{7,0,1575},{7,0, +1917},{8,0,43},{8,0,208},{9,0,128},{9,0,866},{10,0,20},{11,0,981},{147,0,33},{7, +0,893},{141,0,424},{139,10,234},{150,11,56},{5,11,779},{5,11,807},{6,11,1655},{ +134,11,1676},{5,10,802},{7,10,2021},{136,10,805},{4,11,196},{5,10,167},{5,10,899 +},{5,11,558},{5,11,949},{6,10,410},{137,10,777},{137,10,789},{134,10,1705},{8,0, +904},{140,0,787},{6,0,322},{9,0,552},{11,0,274},{13,0,209},{13,0,499},{14,0,85}, +{15,0,126},{145,0,70},{135,10,10},{5,10,11},{6,10,117},{6,10,485},{7,10,1133},{9 +,10,582},{9,10,594},{11,10,21},{11,10,818},{12,10,535},{141,10,86},{4,10,264},{7 +,10,1067},{8,10,204},{8,10,385},{139,10,953},{132,11,752},{138,10,56},{133,10, +470},{6,0,1808},{8,0,83},{8,0,742},{8,0,817},{9,0,28},{9,0,29},{9,0,885},{10,0, +387},{11,0,633},{11,0,740},{13,0,235},{13,0,254},{15,0,143},{143,0,146},{140,0, +49},{134,0,1832},{4,11,227},{5,11,159},{5,11,409},{7,11,80},{10,11,294},{10,11, +479},{12,11,418},{14,11,50},{14,11,249},{142,11,295},{7,11,1470},{8,11,66},{8,11 +,137},{8,11,761},{9,11,638},{11,11,80},{11,11,212},{11,11,368},{11,11,418},{12, +11,8},{13,11,15},{16,11,61},{17,11,59},{19,11,28},{148,11,84},{139,10,1015},{138 +,11,468},{135,0,421},{6,0,415},{7,0,1049},{137,0,442},{6,11,38},{7,11,1220},{8, +11,185},{8,11,256},{9,11,22},{9,11,331},{10,11,738},{11,11,205},{11,11,540},{11, +11,746},{13,11,399},{13,11,465},{14,11,88},{142,11,194},{139,0,289},{133,10,715} +,{4,0,110},{10,0,415},{10,0,597},{142,0,206},{4,11,159},{6,11,115},{7,11,252},{7 +,11,257},{7,11,1928},{8,11,69},{9,11,384},{10,11,91},{10,11,615},{12,11,375},{14 +,11,235},{18,11,117},{147,11,123},{5,11,911},{136,11,278},{7,0,205},{7,0,2000},{ +8,10,794},{9,10,400},{10,10,298},{142,10,228},{135,11,1774},{4,11,151},{7,11, +1567},{8,11,351},{137,11,322},{136,10,724},{133,11,990},{7,0,1539},{7,11,1539},{ +11,0,512},{13,0,205},{19,0,30},{22,0,36},{151,0,19},{5,11,194},{7,11,1662},{9,11 +,90},{140,11,180},{6,10,190},{7,10,768},{135,10,1170},{134,0,1340},{4,0,283},{ +135,0,1194},{133,11,425},{133,11,971},{12,0,549},{14,10,67},{147,10,60},{135,10, +1023},{134,0,1720},{138,11,587},{5,11,72},{6,11,264},{7,11,21},{7,11,46},{7,11, +2013},{8,11,215},{8,11,513},{10,11,266},{139,11,22},{5,0,319},{135,0,534},{6,10, +137},{9,10,75},{9,10,253},{10,10,194},{138,10,444},{6,11,239},{7,0,1180},{7,11, +118},{10,11,95},{11,11,603},{13,11,443},{14,11,160},{15,11,4},{148,0,112},{134, +11,431},{5,11,874},{6,11,1677},{11,10,643},{12,10,115},{143,11,0},{134,0,967},{6 +,11,65},{7,11,939},{7,11,1172},{7,11,1671},{9,11,540},{10,11,696},{11,11,265},{ +11,11,732},{11,11,928},{11,11,937},{12,11,399},{13,11,438},{149,11,19},{137,11, +200},{135,0,1940},{5,10,760},{7,10,542},{8,10,135},{136,10,496},{140,11,44},{7, +11,1655},{136,11,305},{7,10,319},{7,10,355},{7,10,763},{10,10,389},{145,10,43},{ +136,0,735},{138,10,786},{137,11,19},{132,11,696},{5,0,132},{9,0,486},{9,0,715},{ +10,0,458},{11,0,373},{11,0,668},{11,0,795},{11,0,897},{12,0,272},{12,0,424},{12, +0,539},{12,0,558},{14,0,245},{14,0,263},{14,0,264},{14,0,393},{142,0,403},{10,0, +38},{139,0,784},{132,0,838},{4,11,302},{135,11,1766},{133,0,379},{4,11,726},{5,0 +,8},{5,11,630},{6,0,89},{6,0,400},{7,0,1569},{7,0,1623},{7,0,1850},{8,0,218},{8, +0,422},{9,0,570},{138,0,626},{4,0,1017},{138,0,660},{6,0,387},{7,0,882},{141,0, +111},{6,0,224},{7,0,877},{137,0,647},{4,10,58},{5,10,286},{6,10,319},{7,10,402}, +{7,10,1254},{7,10,1903},{8,10,356},{140,10,408},{135,0,790},{4,10,389},{9,0,510} +,{9,10,181},{10,0,53},{10,10,29},{10,10,816},{11,10,311},{11,10,561},{12,10,67}, +{141,10,181},{142,0,458},{6,11,118},{7,11,215},{7,11,1521},{140,11,11},{134,0, +954},{135,0,394},{134,0,1367},{5,10,373},{133,11,225},{132,0,882},{7,0,1409},{ +135,10,1972},{135,10,1793},{4,11,370},{5,11,756},{135,11,1326},{150,11,13},{7,11 +,354},{10,11,410},{139,11,815},{6,11,1662},{7,11,48},{8,11,771},{10,11,116},{13, +11,104},{14,11,105},{14,11,184},{15,11,168},{19,11,92},{148,11,68},{7,0,124},{ +136,0,38},{5,0,261},{7,0,78},{7,0,199},{8,0,815},{9,0,126},{10,0,342},{140,0,647 +},{4,0,628},{140,0,724},{7,0,266},{7,10,1651},{8,0,804},{145,10,89},{135,0,208}, +{134,0,1178},{6,0,79},{135,0,1519},{132,10,672},{133,10,737},{136,0,741},{132,11 +,120},{4,0,710},{6,0,376},{134,0,606},{134,0,1347},{134,0,1494},{6,0,850},{6,0, +1553},{137,0,821},{5,10,145},{134,11,593},{7,0,1311},{140,0,135},{4,0,467},{5,0, +405},{134,0,544},{5,11,820},{135,11,931},{6,0,100},{7,0,244},{7,0,632},{7,0,1609 +},{8,0,178},{8,0,638},{141,0,58},{4,10,387},{135,10,1288},{6,11,151},{6,11,1675} +,{7,11,383},{151,11,10},{132,0,481},{135,10,550},{134,0,1378},{6,11,1624},{11,11 +,11},{12,11,422},{13,11,262},{142,11,360},{133,0,791},{4,11,43},{5,11,344},{133, +11,357},{7,0,1227},{140,0,978},{7,0,686},{8,0,33},{8,0,238},{10,0,616},{11,0,467 +},{11,0,881},{13,0,217},{13,0,253},{142,0,268},{137,0,857},{7,11,148},{8,0,467}, +{8,0,1006},{8,11,284},{141,11,63},{4,10,576},{135,10,1263},{133,11,888},{5,10, +919},{134,10,1673},{20,10,37},{148,11,37},{132,0,447},{132,11,711},{4,0,128},{5, +0,415},{6,0,462},{7,0,294},{7,0,578},{10,0,710},{139,0,86},{4,10,82},{5,10,333}, +{5,10,904},{6,10,207},{7,10,325},{7,10,1726},{8,10,101},{10,10,778},{139,10,220} +,{136,0,587},{137,11,440},{133,10,903},{6,0,427},{7,0,1018},{138,0,692},{4,0,195 +},{135,0,802},{140,10,147},{134,0,1546},{134,0,684},{132,10,705},{136,0,345},{11 +,11,678},{140,11,307},{133,0,365},{134,0,1683},{4,11,65},{5,11,479},{5,11,1004}, +{7,11,1913},{8,11,317},{9,11,302},{10,11,612},{141,11,22},{138,0,472},{4,11,261} +,{135,11,510},{134,10,90},{142,0,433},{151,0,28},{4,11,291},{7,11,101},{9,11,515 +},{12,11,152},{12,11,443},{13,11,392},{142,11,357},{140,0,997},{5,0,3},{8,0,578} +,{9,0,118},{10,0,705},{141,0,279},{135,11,1266},{7,10,813},{12,10,497},{141,10, +56},{133,0,229},{6,10,125},{135,10,1277},{8,0,102},{10,0,578},{10,0,672},{12,0, +496},{13,0,408},{14,0,121},{17,0,106},{151,10,12},{6,0,866},{134,0,1080},{136,0, +1022},{4,11,130},{135,11,843},{5,11,42},{5,11,879},{7,11,245},{7,11,324},{7,11, +1532},{11,11,463},{11,11,472},{13,11,363},{144,11,52},{150,0,55},{4,11,134},{5, +11,372},{8,0,115},{8,0,350},{9,0,489},{10,0,128},{11,0,306},{12,0,373},{14,0,30} +,{17,0,79},{147,0,80},{134,0,657},{134,0,933},{135,11,1147},{4,0,230},{133,0,702 +},{134,0,1728},{4,0,484},{18,0,26},{19,0,42},{20,0,43},{21,0,0},{23,0,27},{152,0 +,14},{7,0,185},{135,0,703},{6,0,417},{7,10,1106},{9,10,770},{10,0,618},{11,10, +112},{140,10,413},{134,0,803},{132,11,644},{134,0,1262},{7,11,540},{12,10,271},{ +145,10,109},{135,11,123},{132,0,633},{134,11,623},{4,11,908},{5,11,359},{5,11, +508},{6,11,1723},{7,11,343},{7,11,1996},{135,11,2026},{135,0,479},{7,10,304},{9, +10,646},{9,10,862},{10,0,262},{11,10,696},{12,10,208},{15,10,79},{147,10,108},{4 +,11,341},{135,11,480},{134,0,830},{5,0,70},{5,0,622},{6,0,334},{7,0,1032},{9,0, +171},{11,0,26},{11,0,213},{11,0,637},{11,0,707},{12,0,202},{12,0,380},{13,0,226} +,{13,0,355},{14,0,222},{145,0,42},{135,10,981},{143,0,217},{137,11,114},{4,0,23} +,{4,0,141},{5,0,313},{5,0,1014},{6,0,50},{6,0,51},{7,0,142},{7,0,384},{7,0,559}, +{8,0,640},{9,0,460},{9,0,783},{11,0,741},{12,0,183},{141,0,488},{141,0,360},{7,0 +,1586},{7,11,1995},{8,11,299},{11,11,890},{140,11,674},{132,10,434},{6,10,550},{ +135,0,652},{5,10,553},{7,0,766},{138,10,824},{7,0,737},{8,0,298},{136,10,452},{4 +,11,238},{5,11,503},{6,11,179},{7,11,2003},{8,11,381},{8,11,473},{9,11,149},{10, +11,183},{15,11,45},{143,11,86},{133,10,292},{5,0,222},{9,0,655},{138,0,534},{138 +,10,135},{4,11,121},{5,11,156},{5,11,349},{9,11,136},{10,11,605},{14,11,342},{ +147,11,107},{137,0,906},{6,0,1013},{134,0,1250},{6,0,1956},{6,0,2009},{8,0,991}, +{144,0,120},{135,11,1192},{138,0,503},{5,0,154},{7,0,1491},{10,0,379},{138,0,485 +},{6,0,1867},{6,0,1914},{6,0,1925},{9,0,917},{9,0,925},{9,0,932},{9,0,951},{9,0, +1007},{9,0,1013},{12,0,806},{12,0,810},{12,0,814},{12,0,816},{12,0,824},{12,0, +832},{12,0,837},{12,0,863},{12,0,868},{12,0,870},{12,0,889},{12,0,892},{12,0,900 +},{12,0,902},{12,0,908},{12,0,933},{12,0,942},{12,0,949},{12,0,954},{15,0,175},{ +15,0,203},{15,0,213},{15,0,218},{15,0,225},{15,0,231},{15,0,239},{15,0,248},{15, +0,252},{18,0,190},{18,0,204},{18,0,215},{18,0,216},{18,0,222},{18,0,225},{18,0, +230},{18,0,239},{18,0,241},{21,0,42},{21,0,43},{21,0,44},{21,0,45},{21,0,46},{21 +,0,53},{24,0,27},{152,0,31},{133,0,716},{135,0,844},{4,0,91},{5,0,388},{5,0,845} +,{6,0,206},{6,0,252},{6,0,365},{7,0,136},{7,0,531},{136,0,621},{7,10,393},{10,10 +,603},{139,10,206},{6,11,80},{6,11,1694},{7,11,173},{7,11,1974},{9,11,547},{10, +11,730},{14,11,18},{150,11,39},{137,0,748},{4,11,923},{134,11,1711},{4,10,912},{ +137,10,232},{7,10,98},{7,10,1973},{136,10,716},{5,10,733},{142,0,103},{132,11, +595},{5,11,240},{6,11,459},{7,11,12},{7,11,114},{7,11,502},{7,11,1751},{7,11, +1753},{7,11,1805},{8,11,658},{9,11,1},{11,11,959},{12,0,158},{13,11,446},{14,11, +211},{18,0,8},{19,0,62},{20,0,6},{22,0,4},{23,0,2},{151,0,9},{135,0,576},{5,0, +771},{5,0,863},{5,0,898},{6,0,648},{6,0,1632},{6,0,1644},{134,0,1780},{133,0,331 +},{7,11,633},{7,11,905},{7,11,909},{7,11,1538},{9,11,767},{140,11,636},{140,0, +632},{5,0,107},{7,0,201},{136,0,518},{6,0,446},{6,11,490},{135,0,1817},{9,0,851} +,{141,0,510},{7,11,250},{8,11,506},{136,11,507},{4,0,504},{137,10,72},{132,11, +158},{4,11,140},{7,11,362},{8,11,209},{9,11,10},{9,11,160},{9,11,503},{10,11,689 +},{11,11,350},{11,11,553},{11,11,725},{12,11,252},{12,11,583},{13,11,192},{13,11 +,352},{14,11,269},{14,11,356},{148,11,50},{6,11,597},{135,11,1318},{135,10,1454} +,{5,0,883},{5,0,975},{8,0,392},{148,0,7},{6,11,228},{7,11,1341},{9,11,408},{138, +11,343},{11,10,600},{11,11,348},{12,11,99},{13,10,245},{18,11,1},{18,11,11},{147 +,11,4},{134,11,296},{5,0,922},{134,0,1707},{132,11,557},{4,11,548},{7,10,164},{7 +,10,1571},{9,10,107},{140,10,225},{7,11,197},{8,11,142},{8,11,325},{9,11,150},{9 +,11,596},{10,11,350},{10,11,353},{11,11,74},{11,11,315},{14,11,423},{143,11,141} +,{5,0,993},{7,0,515},{137,0,91},{4,0,131},{5,10,484},{5,10,510},{6,10,434},{7,10 +,1000},{7,10,1098},{8,0,200},{136,10,2},{152,0,10},{4,11,62},{5,11,83},{6,11,399 +},{6,11,579},{7,11,692},{7,11,846},{7,11,1015},{7,11,1799},{8,11,403},{9,11,394} +,{10,11,133},{12,11,4},{12,11,297},{12,11,452},{16,11,81},{18,11,19},{18,11,25}, +{21,11,14},{22,11,12},{151,11,18},{140,11,459},{132,11,177},{7,0,1433},{9,0,365} +,{137,11,365},{132,10,460},{5,0,103},{5,11,411},{6,0,2004},{7,0,921},{7,11,653}, +{8,0,580},{8,0,593},{8,0,630},{138,0,28},{4,10,932},{133,10,891},{4,0,911},{5,0, +867},{5,0,1013},{7,0,2034},{8,0,798},{136,0,813},{7,11,439},{10,11,727},{11,11, +260},{139,11,684},{136,10,625},{5,11,208},{7,11,753},{135,11,1528},{5,0,461},{6, +10,76},{7,0,1925},{12,0,39},{13,0,265},{141,0,439},{6,0,853},{8,10,92},{137,10, +221},{5,0,135},{6,0,519},{7,0,1722},{10,0,271},{11,0,261},{145,0,54},{139,11,814 +},{14,0,338},{148,0,81},{4,0,300},{133,0,436},{5,0,419},{5,0,687},{7,0,864},{7, +11,864},{137,0,470},{5,11,242},{137,0,836},{134,0,1937},{4,10,763},{133,11,953}, +{132,10,622},{132,0,393},{133,10,253},{7,10,546},{8,0,357},{10,0,745},{14,0,426} +,{17,0,94},{147,0,57},{5,11,615},{146,11,37},{9,10,73},{10,10,110},{14,10,185},{ +145,10,119},{7,10,624},{7,10,916},{10,10,256},{11,0,703},{139,10,87},{133,11,290 +},{5,10,212},{12,10,35},{141,10,382},{132,11,380},{5,11,52},{7,11,277},{9,11,368 +},{139,11,791},{133,0,387},{10,11,138},{139,11,476},{4,0,6},{5,0,708},{136,0,75} +,{7,0,1351},{9,0,581},{10,0,639},{11,0,453},{140,0,584},{132,0,303},{138,0,772}, +{135,10,1175},{4,0,749},{5,10,816},{6,11,256},{7,11,307},{7,11,999},{7,11,1481}, +{7,11,1732},{7,11,1738},{8,11,265},{9,11,414},{11,11,316},{12,11,52},{13,11,420} +,{147,11,100},{135,11,1296},{5,10,869},{5,10,968},{6,0,1065},{6,10,1626},{8,10, +734},{136,10,784},{4,10,542},{6,10,1716},{6,10,1727},{7,10,1082},{7,10,1545},{8, +10,56},{8,10,118},{8,10,412},{8,10,564},{9,10,888},{9,10,908},{10,10,50},{10,10, +423},{11,10,685},{11,10,697},{11,10,933},{12,10,299},{13,10,126},{13,10,136},{13 +,10,170},{141,10,190},{134,0,226},{4,0,106},{5,11,723},{7,0,310},{139,0,717},{4, +10,232},{5,0,890},{5,0,988},{9,10,202},{10,10,474},{140,10,433},{6,0,626},{142,0 +,431},{10,0,706},{150,0,44},{6,10,108},{7,10,1003},{7,10,1181},{8,10,111},{8,10, +343},{141,0,51},{132,0,698},{5,11,109},{6,11,1784},{7,11,1895},{12,11,296},{140, +11,302},{134,0,828},{134,10,1712},{138,0,17},{4,10,133},{5,11,216},{7,0,1929},{7 +,10,711},{7,10,1298},{7,10,1585},{7,11,1879},{9,11,141},{9,11,270},{9,11,679},{ +10,11,159},{10,11,553},{11,11,197},{11,11,438},{12,11,538},{12,11,559},{13,11, +193},{13,11,423},{14,11,144},{14,11,166},{14,11,167},{15,11,67},{147,11,84},{141 +,11,127},{7,11,1872},{137,11,81},{6,10,99},{7,10,1808},{145,10,57},{134,11,391}, +{5,0,689},{6,0,84},{6,10,574},{7,0,1250},{7,10,428},{10,10,669},{11,10,485},{11, +10,840},{12,10,300},{142,10,250},{7,11,322},{136,11,249},{7,11,432},{135,11,1649 +},{135,10,1871},{137,10,252},{6,11,155},{140,11,234},{7,0,871},{19,0,27},{147,11 +,27},{140,0,498},{5,0,986},{6,0,130},{138,0,823},{6,0,1793},{6,10,323},{7,0,1582 +},{7,10,1564},{8,0,458},{10,0,101},{10,0,318},{10,0,945},{12,0,734},{16,0,104},{ +146,0,177},{5,11,632},{138,11,526},{7,10,461},{8,10,775},{138,0,435},{6,11,144}, +{7,11,948},{7,11,1042},{7,11,1857},{8,11,235},{8,11,461},{9,11,453},{9,11,530},{ +10,11,354},{17,11,77},{19,11,99},{148,11,79},{138,0,966},{7,0,1644},{137,0,129}, +{135,0,997},{136,0,502},{5,11,196},{6,11,486},{7,11,212},{8,11,309},{136,11,346} +,{7,10,727},{146,10,73},{132,0,823},{132,11,686},{135,0,1927},{4,0,762},{7,0, +1756},{137,0,98},{136,10,577},{4,11,30},{5,11,43},{24,0,8},{152,11,8},{7,0,1046} +,{139,0,160},{4,10,413},{5,10,677},{7,0,492},{7,11,492},{8,10,432},{140,10,280}, +{6,0,45},{7,0,433},{8,0,129},{9,0,21},{10,0,392},{11,0,79},{12,0,499},{13,0,199} +,{141,0,451},{7,0,558},{136,0,353},{4,11,220},{7,11,1535},{9,11,93},{139,11,474} +,{7,10,646},{7,10,1730},{11,10,446},{141,10,178},{133,0,785},{134,0,1145},{8,0, +81},{9,0,189},{9,0,201},{11,0,478},{11,0,712},{141,0,338},{5,0,353},{151,0,26},{ +4,10,395},{139,0,762},{134,0,2024},{4,0,611},{133,0,606},{9,10,174},{10,10,164}, +{11,10,440},{11,10,841},{143,10,98},{134,10,426},{10,10,608},{139,10,1002},{138, +10,250},{6,0,25},{7,0,855},{7,0,1258},{144,0,32},{7,11,1725},{138,11,393},{5,11, +263},{134,11,414},{5,10,476},{134,0,2011},{4,0,4},{6,11,178},{6,11,1750},{7,0, +1118},{7,0,1320},{7,0,1706},{8,0,277},{8,11,251},{9,0,622},{9,11,690},{10,0,9},{ +10,11,155},{10,11,196},{10,11,373},{11,0,724},{11,11,698},{12,0,350},{12,0,397}, +{13,0,28},{13,0,159},{13,11,155},{15,0,89},{18,0,5},{19,0,9},{20,0,34},{20,11,93 +},{150,0,47},{5,11,97},{137,11,393},{5,10,76},{6,10,458},{6,10,497},{7,0,764},{7 +,10,868},{9,10,658},{10,10,594},{11,0,461},{11,10,566},{12,0,172},{12,10,338},{ +141,10,200},{134,0,1449},{138,11,40},{134,11,1639},{134,0,1445},{4,10,526},{6,0, +1168},{7,10,1029},{135,10,1054},{4,11,191},{7,11,934},{8,11,647},{145,11,97},{ +132,10,636},{6,0,233},{7,10,660},{7,10,1124},{17,10,31},{19,10,22},{151,10,14},{ +6,10,1699},{136,11,110},{12,11,246},{15,11,162},{19,11,64},{20,11,8},{20,11,95}, +{22,11,24},{152,11,17},{5,11,165},{9,11,346},{138,11,655},{5,11,319},{135,11,534 +},{134,0,255},{8,11,128},{9,0,216},{139,11,179},{9,0,183},{139,0,286},{11,0,956} +,{151,0,3},{4,0,536},{7,0,1141},{10,0,723},{139,0,371},{4,10,279},{7,10,301},{ +137,10,362},{5,11,57},{6,11,101},{6,11,1663},{7,0,285},{7,11,132},{7,11,1048},{7 +,11,1154},{7,11,1415},{7,11,1507},{12,11,493},{15,11,105},{151,11,15},{5,11,459} +,{7,10,1743},{7,11,1073},{8,11,241},{136,11,334},{4,10,178},{133,10,399},{135,0, +560},{132,0,690},{135,0,1246},{18,0,157},{147,0,63},{10,0,599},{11,0,33},{12,0, +571},{149,0,1},{6,11,324},{6,11,520},{7,11,338},{7,11,1616},{7,11,1729},{8,11, +228},{9,11,69},{139,11,750},{7,0,1862},{12,0,491},{12,0,520},{13,0,383},{142,0, +244},{135,11,734},{134,10,1692},{6,10,202},{7,11,705},{10,0,448},{11,0,630},{12, +10,360},{17,0,117},{17,10,118},{18,10,27},{148,10,67},{4,11,73},{6,11,612},{7,11 +,927},{7,11,1822},{8,11,217},{9,11,472},{9,11,765},{9,11,766},{10,11,408},{11,11 +,51},{11,11,793},{12,11,266},{15,11,158},{20,11,89},{150,11,32},{4,0,190},{133,0 +,554},{133,0,1001},{5,11,389},{8,11,636},{137,11,229},{5,0,446},{7,10,872},{10, +10,516},{139,10,167},{137,10,313},{132,10,224},{134,0,1313},{5,10,546},{7,10,35} +,{8,10,11},{8,10,12},{9,10,315},{9,10,533},{10,10,802},{11,10,166},{12,10,525},{ +142,10,243},{6,0,636},{137,0,837},{5,10,241},{8,10,242},{9,10,451},{10,10,667},{ +11,10,598},{140,10,429},{22,10,46},{150,11,46},{136,11,472},{11,0,278},{142,0,73 +},{141,11,185},{132,0,868},{134,0,972},{4,10,366},{137,10,516},{138,0,1010},{5, +11,189},{6,10,1736},{7,11,442},{7,11,443},{8,11,281},{12,11,174},{13,11,83},{141 +,11,261},{139,11,384},{6,11,2},{7,11,191},{7,11,446},{7,11,758},{7,11,1262},{7, +11,1737},{8,11,22},{8,11,270},{8,11,612},{9,11,4},{9,11,167},{9,11,312},{9,11, +436},{10,11,156},{10,11,216},{10,11,311},{10,11,623},{11,11,72},{11,11,330},{11, +11,455},{12,11,101},{12,11,321},{12,11,504},{12,11,530},{12,11,543},{13,11,17},{ +13,11,156},{13,11,334},{14,11,48},{15,11,70},{17,11,60},{148,11,64},{6,10,331},{ +136,10,623},{135,0,1231},{132,0,304},{6,11,60},{7,11,670},{7,11,1327},{8,11,411} +,{8,11,435},{9,11,653},{9,11,740},{10,11,385},{11,11,222},{11,11,324},{11,11,829 +},{140,11,611},{6,11,166},{7,0,506},{7,11,374},{135,11,1174},{14,11,43},{146,11, +21},{135,11,1694},{135,10,1888},{5,11,206},{134,11,398},{135,11,50},{150,0,26},{ +6,0,53},{6,0,199},{7,0,1408},{8,0,32},{8,0,93},{10,0,397},{10,0,629},{11,0,593}, +{11,0,763},{13,0,326},{145,0,35},{134,0,105},{132,10,394},{4,0,843},{138,0,794}, +{11,0,704},{141,0,396},{5,0,114},{5,0,255},{141,0,285},{6,0,619},{7,0,898},{7,0, +1092},{7,10,1931},{8,0,485},{18,0,28},{147,0,116},{7,10,574},{7,10,1719},{137,0, +145},{7,0,2035},{8,0,19},{9,0,89},{138,0,831},{132,10,658},{6,11,517},{7,11,1159 +},{10,11,621},{139,11,192},{7,0,1933},{7,11,1933},{9,10,781},{10,10,144},{11,10, +385},{13,10,161},{13,10,228},{13,10,268},{148,10,107},{136,10,374},{10,11,223},{ +139,11,645},{135,0,1728},{7,11,64},{7,11,289},{136,11,245},{4,10,344},{6,10,498} +,{139,10,323},{136,0,746},{135,10,1063},{137,10,155},{4,0,987},{6,0,1964},{6,0, +1974},{6,0,1990},{136,0,995},{133,11,609},{133,10,906},{134,0,1550},{134,0,874}, +{5,11,129},{6,11,61},{135,11,947},{4,0,1018},{6,0,1938},{6,0,2021},{134,0,2039}, +{132,0,814},{11,0,126},{139,0,287},{134,0,1264},{5,0,955},{136,0,814},{141,11, +506},{132,11,314},{6,0,981},{139,11,1000},{5,0,56},{8,0,892},{8,0,915},{140,0, +776},{148,0,100},{10,0,4},{10,0,13},{11,0,638},{148,0,57},{148,11,74},{4,10,616} +,{133,0,738},{133,11,637},{136,10,692},{133,0,758},{132,10,305},{137,11,590},{5, +11,280},{135,11,1226},{134,11,494},{135,0,1112},{133,11,281},{5,10,214},{7,10, +603},{8,10,611},{9,10,686},{10,10,88},{11,10,459},{11,10,496},{12,10,463},{12,10 +,590},{13,0,44},{142,0,214},{139,0,328},{135,11,1064},{137,0,133},{7,0,168},{13, +0,196},{141,0,237},{134,10,1703},{134,0,1152},{135,0,1245},{5,0,110},{6,0,169},{ +6,0,1702},{7,0,400},{8,0,538},{9,0,184},{9,0,524},{140,0,218},{6,0,1816},{10,0, +871},{12,0,769},{140,0,785},{132,11,630},{7,11,33},{7,11,120},{8,11,489},{9,11, +319},{10,11,820},{11,11,1004},{12,11,379},{13,11,117},{13,11,412},{14,11,25},{15 +,11,52},{15,11,161},{16,11,47},{149,11,2},{6,0,133},{8,0,413},{9,0,353},{139,0, +993},{145,10,19},{4,11,937},{133,11,801},{134,0,978},{6,0,93},{6,0,1508},{7,0, +1422},{7,0,1851},{8,0,673},{9,0,529},{140,0,43},{4,10,737},{6,0,317},{10,0,512}, +{11,10,294},{12,10,60},{12,10,437},{13,10,64},{13,10,380},{142,10,430},{7,11, +1591},{9,0,371},{144,11,43},{6,10,1758},{8,10,520},{9,10,345},{9,10,403},{142,10 +,350},{5,0,526},{10,10,242},{138,10,579},{9,0,25},{10,0,467},{138,0,559},{5,10, +139},{7,10,1168},{138,10,539},{4,0,335},{135,0,942},{140,0,754},{132,11,365},{11 +,0,182},{142,0,195},{142,11,29},{5,11,7},{139,11,774},{4,11,746},{135,11,1090},{ +8,0,39},{10,0,773},{11,0,84},{12,0,205},{142,0,1},{5,0,601},{5,0,870},{5,11,360} +,{136,11,237},{132,0,181},{136,0,370},{134,0,1652},{4,10,107},{7,10,613},{8,0, +358},{8,10,439},{8,10,504},{9,10,501},{10,10,383},{139,10,477},{132,10,229},{137 +,11,785},{4,0,97},{5,0,147},{6,0,286},{7,0,1362},{141,0,176},{4,10,903},{6,0,537 +},{7,0,788},{135,0,1816},{140,10,71},{6,0,743},{134,0,1223},{6,0,375},{7,0,169}, +{7,0,254},{7,11,1493},{136,0,780},{4,10,47},{6,10,373},{7,0,1714},{7,10,452},{7, +10,543},{7,10,1856},{9,10,6},{11,10,257},{139,10,391},{6,0,896},{136,0,1003},{ +135,0,1447},{137,11,341},{5,10,980},{134,10,1754},{145,11,22},{4,11,277},{5,11, +608},{6,11,493},{7,11,457},{140,11,384},{7,10,536},{7,10,1331},{136,10,143},{140 +,0,744},{7,11,27},{135,11,316},{5,10,19},{6,10,533},{146,0,126},{4,0,788},{5,11, +552},{5,11,586},{5,11,676},{6,11,448},{8,11,244},{11,0,41},{11,11,1},{11,11,41}, +{13,11,3},{16,11,54},{17,11,4},{146,11,13},{4,0,985},{4,11,401},{6,0,1801},{137, +11,264},{5,10,395},{5,10,951},{134,10,1776},{5,0,629},{135,0,1549},{11,10,663},{ +12,10,210},{13,10,166},{13,10,310},{14,10,373},{147,10,43},{9,11,543},{10,11,524 +},{11,11,30},{12,11,524},{14,11,315},{16,11,18},{20,11,26},{148,11,65},{4,11,205 +},{5,11,623},{7,11,104},{136,11,519},{5,0,293},{134,0,601},{7,11,579},{9,11,41}, +{9,11,244},{9,11,669},{10,11,5},{11,11,861},{11,11,951},{139,11,980},{132,11,717 +},{132,10,695},{7,10,497},{9,10,387},{147,10,81},{132,0,420},{142,0,37},{6,0, +1134},{6,0,1900},{12,0,830},{12,0,878},{12,0,894},{15,0,221},{143,0,245},{132,11 +,489},{7,0,1570},{140,0,542},{8,0,933},{136,0,957},{5,10,284},{6,0,1371},{6,10, +49},{6,10,350},{7,0,31},{7,10,377},{7,10,1693},{8,0,373},{8,10,678},{9,10,161},{ +9,10,585},{9,10,671},{9,10,839},{11,10,912},{141,10,427},{135,11,892},{4,0,325}, +{138,0,125},{139,11,47},{132,10,597},{138,0,323},{6,0,1547},{7,11,1605},{9,11, +473},{11,11,962},{146,11,139},{139,10,908},{7,11,819},{9,11,26},{9,11,392},{10, +11,152},{10,11,226},{11,11,19},{12,11,276},{12,11,426},{12,11,589},{13,11,460},{ +15,11,97},{19,11,48},{148,11,104},{135,11,51},{4,0,718},{135,0,1216},{6,0,1896}, +{6,0,1905},{6,0,1912},{7,11,761},{7,11,1051},{9,0,947},{9,0,974},{9,11,545},{12, +0,809},{12,0,850},{12,0,858},{12,0,874},{12,0,887},{12,0,904},{12,0,929},{12,0, +948},{12,0,952},{15,0,198},{15,0,206},{15,0,220},{15,0,227},{15,0,247},{18,0,188 +},{21,0,48},{21,0,50},{24,0,25},{152,0,29},{5,0,124},{5,0,144},{6,0,548},{7,0,15 +},{7,0,153},{137,0,629},{135,11,606},{135,10,2014},{7,10,2007},{9,10,101},{9,10, +450},{9,11,46},{10,10,66},{10,10,842},{11,10,536},{140,10,587},{6,0,75},{7,0, +1531},{8,0,416},{9,0,240},{9,0,275},{10,0,100},{11,0,658},{11,0,979},{12,0,86},{ +14,0,207},{15,0,20},{143,0,25},{5,0,141},{5,0,915},{6,0,1783},{7,0,211},{7,0,698 +},{7,0,1353},{9,0,83},{9,0,281},{10,0,376},{10,0,431},{11,0,543},{12,0,664},{13, +0,280},{13,0,428},{14,0,61},{14,0,128},{17,0,52},{145,0,81},{132,11,674},{135,0, +533},{149,0,6},{132,11,770},{133,0,538},{5,11,79},{7,11,1027},{7,11,1477},{139, +11,52},{139,10,62},{4,0,338},{133,0,400},{5,11,789},{134,11,195},{4,11,251},{4, +11,688},{7,11,513},{7,11,1284},{9,11,87},{138,11,365},{134,10,1766},{6,0,0},{7,0 +,84},{11,0,895},{145,0,11},{139,0,892},{4,0,221},{5,0,659},{7,0,697},{7,0,1211}, +{138,0,284},{133,0,989},{133,11,889},{4,11,160},{5,11,330},{7,11,1434},{136,11, +174},{6,10,1665},{7,10,256},{7,10,1388},{10,10,499},{139,10,670},{4,10,22},{5,10 +,10},{7,0,848},{136,10,97},{138,0,507},{133,10,481},{4,0,188},{135,0,805},{5,0, +884},{6,0,732},{139,0,991},{135,11,968},{11,11,636},{15,11,145},{17,11,34},{19, +11,50},{151,11,20},{6,10,134},{7,0,959},{7,10,437},{9,10,37},{14,10,285},{14,10, +371},{144,0,60},{7,10,486},{8,10,155},{11,10,93},{140,10,164},{134,0,1653},{5,10 +,591},{135,0,337},{5,11,374},{6,0,1989},{8,0,922},{136,0,978},{132,0,638},{138,0 +,500},{133,11,731},{5,10,380},{5,10,650},{136,10,310},{138,11,381},{4,10,364},{7 +,10,1156},{7,10,1187},{137,10,409},{137,11,224},{140,0,166},{134,10,482},{4,11, +626},{5,11,642},{6,11,425},{10,11,202},{139,11,141},{4,10,781},{6,10,487},{7,10, +926},{8,10,263},{139,10,500},{135,0,418},{4,10,94},{135,10,1265},{136,0,760},{ +132,10,417},{136,11,835},{5,10,348},{134,10,522},{6,0,1277},{134,0,1538},{139,11 +,541},{135,11,1597},{5,11,384},{8,11,455},{140,11,48},{136,0,770},{5,11,264},{ +134,11,184},{4,0,89},{5,0,489},{6,0,315},{7,0,553},{7,0,1745},{138,0,243},{4,10, +408},{4,10,741},{135,10,500},{134,0,1396},{133,0,560},{6,0,1658},{9,0,3},{10,0, +154},{11,0,641},{13,0,85},{13,0,201},{141,0,346},{135,11,1595},{5,11,633},{6,11, +28},{7,11,219},{135,11,1323},{9,11,769},{140,11,185},{135,11,785},{7,11,359},{8, +11,243},{140,11,175},{138,0,586},{6,10,73},{135,0,1271},{132,11,105},{4,0,166},{ +5,0,505},{134,0,1670},{133,10,576},{4,11,324},{138,11,104},{142,10,231},{6,0,637 +},{7,10,1264},{7,10,1678},{11,10,945},{12,10,341},{12,10,471},{12,10,569},{23,11 +,21},{151,11,23},{8,11,559},{141,11,109},{134,0,1947},{7,0,445},{8,0,307},{8,0, +704},{10,0,41},{10,0,439},{11,0,237},{11,0,622},{140,0,201},{135,11,963},{135,0, +1977},{4,0,189},{5,0,713},{136,0,57},{138,0,371},{135,10,538},{132,0,552},{5,10, +413},{134,0,883},{4,11,758},{134,0,923},{138,11,215},{136,10,495},{7,10,54},{8, +10,312},{10,10,191},{10,10,614},{140,10,567},{7,11,351},{139,11,128},{6,10,468}, +{7,0,875},{7,10,1478},{8,10,530},{142,10,290},{135,0,1788},{5,11,918},{145,0,49} +,{12,11,398},{20,11,39},{21,11,11},{150,11,41},{6,10,484},{7,10,822},{138,0,661} +,{135,0,1945},{134,0,794},{137,10,900},{135,10,1335},{6,10,1724},{135,10,2022},{ +132,11,340},{134,0,1135},{4,0,784},{133,0,745},{5,0,84},{134,0,163},{133,0,410}, +{4,0,976},{5,11,985},{7,11,509},{7,11,529},{145,11,96},{132,10,474},{134,0,703}, +{135,11,1919},{5,0,322},{8,0,186},{9,0,262},{10,0,187},{142,0,208},{135,10,1504} +,{133,0,227},{5,10,305},{9,0,560},{141,0,208},{132,11,247},{7,0,1395},{8,0,486}, +{9,0,236},{9,0,878},{10,0,218},{11,0,95},{19,0,17},{147,0,31},{7,0,2043},{8,0, +672},{141,0,448},{4,11,184},{5,11,390},{6,11,337},{7,11,23},{7,11,494},{7,11,618 +},{7,11,1456},{8,11,27},{8,11,599},{10,11,153},{139,11,710},{135,0,466},{135,10, +1236},{4,10,480},{6,0,167},{6,10,302},{6,10,1642},{7,0,186},{7,0,656},{7,10,837} +,{7,10,1547},{7,10,1657},{8,10,429},{9,10,228},{10,0,643},{13,10,289},{13,10,343 +},{147,10,101},{134,0,1428},{134,0,1440},{5,0,412},{7,10,278},{10,10,739},{11,10 +,708},{141,10,348},{134,0,1118},{136,0,562},{148,11,46},{9,0,316},{139,0,256},{ +134,0,1771},{135,0,1190},{137,0,132},{10,11,227},{11,11,497},{11,11,709},{140,11 +,415},{143,0,66},{6,11,360},{7,11,1664},{136,11,478},{144,10,28},{4,0,317},{135, +0,1279},{5,0,63},{133,0,509},{136,11,699},{145,10,36},{134,0,1475},{11,11,343},{ +142,11,127},{132,11,739},{132,0,288},{135,11,1757},{8,0,89},{8,0,620},{9,0,608}, +{11,0,628},{12,0,322},{143,0,124},{134,0,1225},{4,11,67},{5,11,422},{6,10,363},{ +7,0,1189},{7,10,1955},{7,11,1037},{7,11,1289},{7,11,1555},{8,10,725},{9,11,741}, +{145,11,108},{134,0,1468},{6,0,689},{134,0,1451},{138,0,120},{151,0,1},{137,10, +805},{142,0,329},{5,10,813},{135,10,2046},{135,0,226},{138,11,96},{5,10,712},{7, +0,1855},{11,10,17},{13,10,321},{144,10,67},{6,10,320},{7,10,781},{7,10,1921},{9, +0,461},{9,10,55},{10,10,186},{10,10,273},{10,10,664},{10,10,801},{11,10,996},{11 +,10,997},{13,10,157},{142,10,170},{8,10,271},{8,11,203},{11,11,823},{11,11,846}, +{12,11,482},{13,11,133},{13,11,277},{13,11,302},{13,11,464},{14,11,205},{142,11, +221},{135,0,1346},{4,11,449},{133,11,718},{134,0,85},{7,10,103},{7,10,863},{11, +10,184},{14,0,299},{145,10,62},{4,11,355},{6,11,311},{9,11,256},{138,11,404},{ +137,10,659},{138,11,758},{133,11,827},{5,11,64},{140,11,581},{134,0,1171},{4,11, +442},{7,11,1047},{7,11,1352},{135,11,1643},{132,0,980},{5,11,977},{6,11,288},{7, +11,528},{135,11,1065},{5,0,279},{6,0,235},{7,0,468},{8,0,446},{9,0,637},{10,0, +717},{11,0,738},{140,0,514},{132,0,293},{11,10,337},{142,10,303},{136,11,285},{4 +,11,254},{5,0,17},{6,0,371},{9,0,528},{140,0,364},{5,10,77},{7,10,1455},{10,10, +843},{147,10,73},{150,0,5},{132,10,458},{6,11,12},{7,11,1219},{145,11,73},{135, +10,1420},{6,10,109},{138,10,382},{135,11,125},{6,10,330},{7,10,1084},{139,10,142 +},{6,11,369},{6,11,502},{7,11,1036},{8,11,348},{9,11,452},{10,11,26},{11,11,224} +,{11,11,387},{11,11,772},{12,11,95},{12,11,629},{13,11,195},{13,11,207},{13,11, +241},{14,11,260},{14,11,270},{143,11,140},{132,11,269},{5,11,480},{7,11,532},{7, +11,1197},{7,11,1358},{8,11,291},{11,11,349},{142,11,396},{150,0,48},{10,0,601},{ +13,0,353},{141,0,376},{5,0,779},{5,0,807},{6,0,1655},{134,0,1676},{142,11,223},{ +4,0,196},{5,0,558},{133,0,949},{148,11,15},{135,11,1764},{134,0,1322},{132,0,752 +},{139,0,737},{135,11,657},{136,11,533},{135,0,412},{4,0,227},{5,0,159},{5,0,409 +},{7,0,80},{8,0,556},{10,0,479},{12,0,418},{14,0,50},{14,0,123},{14,0,192},{14,0 +,249},{14,0,295},{143,0,27},{7,0,1470},{8,0,66},{8,0,137},{8,0,761},{9,0,638},{ +11,0,80},{11,0,212},{11,0,368},{11,0,418},{12,0,8},{13,0,15},{16,0,61},{17,0,59} +,{19,0,28},{148,0,84},{135,10,1985},{4,11,211},{4,11,332},{5,11,335},{6,11,238}, +{7,11,269},{7,11,811},{7,11,1797},{8,10,122},{8,11,836},{9,11,507},{141,11,242}, +{6,0,683},{134,0,1252},{4,0,873},{132,10,234},{134,0,835},{6,0,38},{7,0,1220},{8 +,0,185},{8,0,256},{9,0,22},{9,0,331},{10,0,738},{11,0,205},{11,0,540},{11,0,746} +,{13,0,465},{14,0,88},{142,0,194},{138,0,986},{5,11,1009},{12,11,582},{146,11, +131},{4,0,159},{6,0,115},{7,0,252},{7,0,257},{7,0,1928},{8,0,69},{9,0,384},{10,0 +,91},{10,0,615},{12,0,375},{14,0,235},{18,0,117},{147,0,123},{133,0,911},{136,0, +278},{5,10,430},{5,10,932},{6,10,131},{7,10,417},{9,10,522},{11,10,314},{141,10, +390},{14,10,149},{14,10,399},{143,10,57},{4,0,151},{7,0,1567},{136,0,749},{5,11, +228},{6,11,203},{7,11,156},{8,11,347},{137,11,265},{132,10,507},{10,0,989},{140, +0,956},{133,0,990},{5,0,194},{6,0,927},{7,0,1662},{9,0,90},{140,0,564},{4,10,343 +},{133,10,511},{133,0,425},{7,10,455},{138,10,591},{4,0,774},{7,11,476},{7,11, +1592},{138,11,87},{5,0,971},{135,10,1381},{5,11,318},{147,11,121},{5,11,291},{7, +11,765},{9,11,389},{140,11,548},{134,10,575},{4,0,827},{12,0,646},{12,0,705},{12 +,0,712},{140,0,714},{139,0,752},{137,0,662},{5,0,72},{6,0,264},{7,0,21},{7,0,46} +,{7,0,2013},{8,0,215},{8,0,513},{10,0,266},{139,0,22},{139,11,522},{6,0,239},{7, +0,118},{10,0,95},{11,0,603},{13,0,443},{14,0,160},{143,0,4},{6,0,431},{134,0,669 +},{7,10,1127},{7,10,1572},{10,10,297},{10,10,422},{11,10,764},{11,10,810},{12,10 +,264},{13,10,102},{13,10,300},{13,10,484},{14,10,147},{14,10,229},{17,10,71},{18 +,10,118},{147,10,120},{5,0,874},{6,0,1677},{10,11,525},{11,11,82},{143,0,0},{6,0 +,65},{7,0,939},{7,0,1172},{7,0,1671},{9,0,540},{10,0,696},{11,0,265},{11,0,732}, +{11,0,928},{11,0,937},{141,0,438},{134,0,1350},{136,11,547},{132,11,422},{5,11, +355},{145,11,0},{137,11,905},{5,0,682},{135,0,1887},{132,0,809},{4,0,696},{133, +11,865},{6,0,1074},{6,0,1472},{14,10,35},{142,10,191},{5,11,914},{134,11,1625},{ +133,11,234},{135,11,1383},{137,11,780},{132,10,125},{4,0,726},{133,0,630},{8,0, +802},{136,0,838},{132,10,721},{6,0,1337},{7,0,776},{8,10,145},{147,0,56},{132,0, +970},{7,10,792},{8,10,147},{10,10,821},{139,10,1021},{139,10,970},{8,0,940},{137 +,0,797},{135,11,1312},{7,10,1999},{7,11,816},{7,11,1241},{9,0,248},{9,11,283},{9 +,11,520},{10,0,400},{10,11,213},{10,11,307},{10,11,463},{10,11,671},{10,11,746}, +{11,11,401},{11,11,794},{12,11,517},{18,11,107},{147,11,115},{6,0,1951},{134,0, +2040},{135,11,339},{5,10,168},{5,10,930},{8,10,74},{9,10,623},{12,10,500},{12,10 +,579},{13,0,41},{143,0,93},{6,0,118},{7,0,215},{7,0,1521},{140,0,11},{6,10,220}, +{7,10,1101},{141,10,105},{6,11,421},{7,11,61},{7,11,1540},{10,11,11},{138,11,501 +},{7,0,615},{138,0,251},{140,11,631},{135,0,1044},{6,10,19},{7,10,1413},{139,10, +428},{133,0,225},{7,10,96},{8,10,401},{8,10,703},{137,10,896},{145,10,116},{6,11 +,102},{7,11,72},{15,11,142},{147,11,67},{7,10,1961},{7,10,1965},{8,10,702},{136, +10,750},{7,10,2030},{8,10,150},{8,10,737},{12,10,366},{151,11,30},{4,0,370},{5,0 +,756},{7,0,1326},{135,11,823},{8,10,800},{9,10,148},{9,10,872},{9,10,890},{11,10 +,309},{11,10,1001},{13,10,267},{141,10,323},{6,0,1662},{7,0,48},{8,0,771},{10,0, +116},{13,0,104},{14,0,105},{14,0,184},{15,0,168},{19,0,92},{148,0,68},{7,11,1870 +},{138,0,209},{7,11,68},{8,11,48},{8,11,88},{8,11,582},{8,11,681},{9,11,373},{9, +11,864},{11,11,157},{11,11,336},{11,11,843},{148,11,27},{134,0,930},{4,11,88},{5 +,11,137},{5,11,174},{5,11,777},{6,11,1664},{6,11,1725},{7,11,77},{7,11,426},{7, +11,1317},{7,11,1355},{8,11,126},{8,11,563},{9,11,523},{9,11,750},{10,11,310},{10 +,11,836},{11,11,42},{11,11,318},{11,11,731},{12,11,68},{12,11,92},{12,11,507},{ +12,11,692},{13,11,81},{13,11,238},{13,11,374},{18,11,138},{19,11,78},{19,11,111} +,{20,11,55},{20,11,77},{148,11,92},{4,11,938},{135,11,1831},{5,10,547},{7,10,424 +},{8,11,617},{138,11,351},{6,0,1286},{6,11,1668},{7,11,1499},{8,11,117},{9,11, +314},{138,11,174},{6,0,759},{6,0,894},{7,11,707},{139,11,563},{4,0,120},{135,0, +1894},{9,0,385},{149,0,17},{138,0,429},{133,11,403},{5,0,820},{135,0,931},{5,10, +133},{138,0,199},{6,0,151},{6,0,1675},{7,0,383},{151,0,10},{6,0,761},{136,10,187 +},{8,0,365},{10,10,0},{10,10,818},{139,10,988},{4,11,44},{5,11,311},{6,11,156},{ +7,11,639},{7,11,762},{7,11,1827},{9,11,8},{9,11,462},{148,11,83},{4,11,346},{7, +11,115},{9,11,180},{9,11,456},{138,11,363},{136,10,685},{7,0,1086},{145,0,46},{6 +,0,1624},{11,0,11},{12,0,422},{13,0,444},{142,0,360},{6,0,1020},{6,0,1260},{134, +0,1589},{4,0,43},{5,0,344},{5,0,357},{14,0,472},{150,0,58},{6,0,1864},{6,0,1866} +,{6,0,1868},{6,0,1869},{6,0,1874},{6,0,1877},{6,0,1903},{6,0,1911},{9,0,920},{9, +0,921},{9,0,924},{9,0,946},{9,0,959},{9,0,963},{9,0,970},{9,0,997},{9,0,1008},{9 +,0,1017},{12,0,795},{12,0,797},{12,0,798},{12,0,800},{12,0,803},{12,0,811},{12,0 +,820},{12,0,821},{12,0,839},{12,0,841},{12,0,848},{12,0,911},{12,0,921},{12,0, +922},{12,0,925},{12,0,937},{12,0,944},{12,0,945},{12,0,953},{15,0,184},{15,0,191 +},{15,0,199},{15,0,237},{15,0,240},{15,0,243},{15,0,246},{18,0,203},{21,0,40},{ +21,0,52},{21,0,57},{24,0,23},{24,0,28},{152,0,30},{134,0,725},{145,11,58},{133,0 +,888},{137,10,874},{4,0,711},{8,10,774},{10,10,670},{140,10,51},{144,11,40},{6, +11,185},{7,11,1899},{139,11,673},{137,10,701},{137,0,440},{4,11,327},{5,11,478}, +{7,11,1332},{8,11,753},{140,11,227},{4,10,127},{5,10,350},{6,10,356},{8,10,426}, +{9,10,572},{10,10,247},{139,10,312},{5,11,1020},{133,11,1022},{4,11,103},{133,11 +,401},{6,0,1913},{6,0,1926},{6,0,1959},{9,0,914},{9,0,939},{9,0,952},{9,0,979},{ +9,0,990},{9,0,998},{9,0,1003},{9,0,1023},{12,0,827},{12,0,834},{12,0,845},{12,0, +912},{12,0,935},{12,0,951},{15,0,172},{15,0,174},{18,0,198},{149,0,63},{4,11,499 +},{5,0,958},{5,0,987},{135,11,1421},{6,10,59},{6,10,1762},{7,0,885},{9,10,603},{ +141,10,397},{10,11,62},{141,11,164},{4,0,847},{135,0,326},{11,0,276},{142,0,293} +,{4,0,65},{4,11,96},{5,0,479},{5,0,1004},{7,0,1913},{8,0,317},{9,0,302},{10,0, +612},{141,0,22},{4,0,261},{135,0,510},{135,0,1514},{6,10,111},{7,10,4},{8,10,163 +},{8,10,776},{138,10,566},{4,0,291},{9,0,515},{12,0,152},{12,0,443},{13,0,392},{ +142,0,357},{7,11,399},{135,11,1492},{4,0,589},{139,0,282},{6,11,563},{135,10, +1994},{5,10,297},{135,10,1038},{4,0,130},{7,0,843},{135,0,1562},{5,0,42},{5,0, +879},{7,0,245},{7,0,324},{7,0,1532},{11,0,463},{11,0,472},{13,0,363},{144,0,52}, +{4,0,134},{133,0,372},{133,0,680},{136,10,363},{6,0,1997},{8,0,935},{136,0,977}, +{4,0,810},{135,0,1634},{135,10,1675},{4,11,910},{5,11,832},{135,0,1390},{7,10, +808},{8,11,266},{139,11,578},{132,0,644},{4,0,982},{138,0,867},{132,10,280},{135 +,0,540},{140,10,54},{135,0,123},{134,0,1978},{4,10,421},{133,10,548},{6,0,623},{ +136,0,789},{4,0,908},{5,0,359},{5,0,508},{6,0,1723},{7,0,343},{7,0,1996},{135,0, +2026},{134,0,1220},{4,0,341},{135,0,480},{6,10,254},{9,10,109},{138,10,103},{134 +,0,888},{8,11,528},{137,11,348},{4,11,20},{5,11,616},{7,0,1995},{8,0,299},{11,0, +890},{140,0,674},{135,11,1094},{134,10,1630},{4,0,238},{5,0,503},{6,0,179},{7,0, +2003},{8,0,381},{8,0,473},{9,0,149},{10,0,788},{15,0,45},{15,0,86},{20,0,110},{ +150,0,57},{133,10,671},{4,11,26},{5,11,429},{6,11,245},{7,11,704},{7,11,1379},{ +135,11,1474},{4,0,121},{5,0,156},{5,0,349},{9,0,431},{10,0,605},{142,0,342},{7, +11,943},{139,11,614},{132,10,889},{132,11,621},{7,10,1382},{7,10,1910},{135,11, +1382},{132,10,627},{133,10,775},{133,11,542},{133,11,868},{136,11,433},{6,0,1373 +},{7,0,1011},{11,10,362},{11,10,948},{140,10,388},{6,0,80},{7,0,173},{7,11,1495} +,{9,0,547},{10,0,730},{14,0,18},{150,0,39},{6,0,1694},{135,0,1974},{140,0,196},{ +4,0,923},{6,0,507},{6,0,1711},{7,10,451},{8,10,389},{12,10,490},{13,10,16},{13, +10,215},{13,10,351},{18,10,132},{147,10,125},{6,0,646},{134,0,1047},{135,10,841} +,{136,10,566},{6,0,1611},{135,0,1214},{139,0,926},{132,11,525},{132,0,595},{5,0, +240},{6,0,459},{7,0,12},{7,0,114},{7,0,949},{7,0,1753},{7,0,1805},{8,0,658},{9,0 +,1},{11,0,959},{141,0,446},{5,10,912},{134,10,1695},{132,0,446},{7,11,62},{12,11 +,45},{147,11,112},{5,10,236},{6,10,572},{8,10,492},{11,10,618},{144,10,56},{5,10 +,190},{136,10,318},{135,10,1376},{4,11,223},{6,11,359},{11,11,3},{13,11,108},{14 +,11,89},{144,11,22},{132,11,647},{134,0,490},{134,0,491},{134,0,1584},{135,11, +685},{138,11,220},{7,0,250},{136,0,507},{132,0,158},{4,0,140},{7,0,362},{8,0,209 +},{9,0,10},{9,0,160},{9,0,503},{9,0,614},{10,0,689},{11,0,327},{11,0,553},{11,0, +725},{11,0,767},{12,0,252},{12,0,583},{13,0,192},{14,0,269},{14,0,356},{148,0,50 +},{19,0,1},{19,0,26},{150,0,9},{132,11,109},{6,0,228},{7,0,1341},{9,0,408},{138, +0,343},{4,0,373},{5,0,283},{6,0,480},{7,0,609},{10,0,860},{138,0,878},{6,0,779}, +{134,0,1209},{4,0,557},{7,11,263},{7,11,628},{136,11,349},{132,0,548},{7,0,197}, +{8,0,142},{8,0,325},{9,0,150},{9,0,596},{10,0,350},{10,0,353},{11,0,74},{11,0, +315},{12,0,662},{12,0,681},{14,0,423},{143,0,141},{4,11,40},{10,11,67},{11,11, +117},{11,11,768},{139,11,935},{7,11,992},{8,11,301},{9,11,722},{12,11,63},{13,11 +,29},{14,11,161},{143,11,18},{6,0,1490},{138,11,532},{5,0,580},{7,0,378},{7,0, +674},{7,0,1424},{15,0,83},{15,11,83},{16,0,11},{144,11,11},{6,0,1057},{6,0,1335} +,{7,10,85},{7,10,247},{8,10,585},{10,0,316},{138,10,163},{4,0,169},{5,0,83},{6,0 +,399},{6,0,579},{6,0,1513},{7,0,692},{7,0,846},{7,0,1015},{7,0,1799},{8,0,403},{ +9,0,394},{10,0,133},{12,0,4},{12,0,297},{12,0,452},{16,0,81},{18,0,25},{21,0,14} +,{22,0,12},{151,0,18},{134,0,1106},{7,0,1546},{11,0,299},{142,0,407},{134,0,1192 +},{132,0,177},{5,0,411},{135,0,653},{7,0,439},{10,0,727},{11,0,260},{139,0,684}, +{138,10,145},{147,10,83},{5,0,208},{7,0,753},{135,0,1528},{137,11,617},{135,10, +1922},{135,11,825},{4,10,124},{10,10,457},{11,0,422},{11,10,121},{11,10,169},{11 +,10,870},{12,10,214},{13,0,389},{14,10,187},{143,10,77},{11,0,615},{11,11,615},{ +15,0,58},{143,11,58},{9,0,618},{138,0,482},{6,0,1952},{6,0,1970},{142,0,505},{7, +10,1193},{135,11,1838},{133,0,242},{135,10,1333},{6,10,107},{7,10,638},{7,10, +1632},{137,10,396},{133,0,953},{5,10,370},{134,10,1756},{5,11,28},{6,11,204},{10 +,11,320},{10,11,583},{13,11,502},{14,11,72},{14,11,274},{14,11,312},{14,11,344}, +{15,11,159},{16,11,62},{16,11,69},{17,11,30},{18,11,42},{18,11,53},{18,11,84},{ +18,11,140},{19,11,68},{19,11,85},{20,11,5},{20,11,45},{20,11,101},{22,11,7},{150 +,11,20},{4,11,558},{6,11,390},{7,11,162},{7,11,689},{9,11,360},{138,11,653},{11, +0,802},{141,0,67},{133,10,204},{133,0,290},{5,10,970},{134,10,1706},{132,0,380}, +{5,0,52},{7,0,277},{9,0,368},{139,0,791},{5,11,856},{6,11,1672},{6,11,1757},{6, +11,1781},{7,11,1150},{7,11,1425},{7,11,1453},{140,11,513},{5,11,92},{7,10,3},{10 +,11,736},{140,11,102},{4,0,112},{5,0,653},{5,10,483},{5,10,685},{6,10,489},{7,10 +,1204},{136,10,394},{132,10,921},{5,10,1007},{134,0,1028},{5,11,590},{9,11,213}, +{145,11,91},{135,10,1696},{10,0,138},{139,0,476},{5,0,725},{5,0,727},{135,0,1811 +},{4,0,979},{6,0,1821},{6,0,1838},{8,0,876},{8,0,883},{8,0,889},{8,0,893},{8,0, +895},{10,0,934},{12,0,720},{14,0,459},{148,0,123},{135,11,551},{4,0,38},{6,0,435 +},{7,0,307},{7,0,999},{7,0,1481},{7,0,1732},{7,0,1738},{8,0,371},{9,0,414},{11,0 +,316},{12,0,52},{13,0,420},{147,0,100},{135,0,1296},{132,10,712},{134,10,1629},{ +133,0,723},{134,0,651},{136,11,191},{9,11,791},{10,11,93},{11,11,301},{16,11,13} +,{17,11,23},{18,11,135},{19,11,12},{20,11,1},{20,11,12},{148,11,14},{136,11,503} +,{6,11,466},{135,11,671},{6,0,1200},{134,0,1330},{135,0,1255},{134,0,986},{5,0, +109},{6,0,1784},{7,0,1895},{12,0,296},{140,0,302},{135,11,983},{133,10,485},{134 +,0,660},{134,0,800},{4,10,285},{5,0,216},{5,0,294},{5,10,317},{6,0,591},{6,10, +301},{7,0,1879},{7,10,7},{8,10,153},{9,0,141},{9,0,270},{9,0,679},{10,0,159},{10 +,10,766},{11,0,197},{11,0,438},{11,10,468},{12,0,538},{12,0,559},{12,10,467},{13 +,10,143},{14,0,144},{14,0,167},{143,0,67},{136,0,945},{134,0,1090},{137,0,81},{ +12,11,468},{19,11,96},{148,11,24},{134,0,391},{138,11,241},{7,0,322},{136,0,249} +,{134,0,1412},{135,11,795},{5,0,632},{138,0,526},{136,10,819},{6,0,144},{7,0,948 +},{7,0,1042},{7,11,954},{8,0,235},{8,0,461},{9,0,453},{9,0,796},{10,0,354},{145, +0,77},{139,10,917},{6,0,940},{134,0,1228},{4,0,362},{7,0,52},{135,0,303},{6,11, +549},{8,11,34},{8,11,283},{9,11,165},{138,11,475},{7,11,370},{7,11,1007},{7,11, +1177},{135,11,1565},{5,11,652},{5,11,701},{135,11,449},{5,0,196},{6,0,486},{7,0, +212},{8,0,309},{136,0,346},{6,10,1719},{6,10,1735},{7,10,2016},{7,10,2020},{8,10 +,837},{137,10,852},{6,11,159},{6,11,364},{7,11,516},{7,11,1439},{137,11,518},{ +135,0,1912},{135,0,1290},{132,0,686},{141,11,151},{138,0,625},{136,0,706},{138, +10,568},{139,0,412},{4,0,30},{133,0,43},{8,10,67},{138,10,419},{7,0,967},{141,0, +11},{12,0,758},{14,0,441},{142,0,462},{10,10,657},{14,10,297},{142,10,361},{139, +10,729},{4,0,220},{135,0,1535},{7,11,501},{9,11,111},{10,11,141},{11,11,332},{13 +,11,43},{13,11,429},{14,11,130},{14,11,415},{145,11,102},{4,0,950},{6,0,1859},{7 +,0,11},{8,0,873},{12,0,710},{12,0,718},{12,0,748},{12,0,765},{148,0,124},{5,11, +149},{5,11,935},{136,11,233},{142,11,291},{134,0,1579},{7,0,890},{8,10,51},{9,10 +,868},{10,10,833},{12,10,481},{12,10,570},{148,10,106},{141,0,2},{132,10,445},{ +136,11,801},{135,0,1774},{7,0,1725},{138,0,393},{5,0,263},{134,0,414},{132,11, +322},{133,10,239},{7,0,456},{7,10,1990},{8,10,130},{139,10,720},{137,0,818},{5, +10,123},{6,10,530},{7,10,348},{135,10,1419},{135,10,2024},{6,0,178},{6,0,1750},{ +8,0,251},{9,0,690},{10,0,155},{10,0,196},{10,0,373},{11,0,698},{13,0,155},{148,0 +,93},{5,0,97},{137,0,393},{134,0,674},{11,0,223},{140,0,168},{132,10,210},{139, +11,464},{6,0,1639},{146,0,159},{139,11,2},{7,0,934},{8,0,647},{17,0,97},{19,0,59 +},{150,0,2},{132,0,191},{4,10,430},{5,0,165},{7,11,357},{9,0,346},{10,0,655},{ +139,0,885},{133,0,877},{5,10,213},{133,11,406},{8,0,128},{139,0,179},{6,11,69},{ +135,11,117},{135,0,1297},{11,11,43},{13,11,72},{141,11,142},{135,11,1830},{142,0 +,164},{5,0,57},{6,0,101},{6,0,586},{6,0,1663},{7,0,132},{7,0,1154},{7,0,1415},{7 +,0,1507},{12,0,493},{15,0,105},{151,0,15},{5,0,459},{7,0,1073},{8,0,241},{136,0, +334},{133,11,826},{133,10,108},{5,10,219},{10,11,132},{11,11,191},{11,11,358},{ +139,11,460},{6,0,324},{6,0,520},{7,0,338},{7,0,1729},{8,0,228},{139,0,750},{4,10 +,193},{5,10,916},{7,10,364},{10,10,398},{10,10,726},{11,10,317},{11,10,626},{12, +10,142},{12,10,288},{12,10,678},{13,10,313},{15,10,113},{18,10,114},{21,0,30},{ +150,0,53},{6,11,110},{135,11,1681},{135,0,910},{6,10,241},{7,10,907},{8,10,832}, +{9,10,342},{10,10,729},{11,10,284},{11,10,445},{11,10,651},{11,10,863},{13,10, +398},{146,10,99},{5,11,1000},{7,0,705},{7,11,733},{9,0,734},{137,11,583},{4,0,73 +},{6,0,612},{7,0,927},{7,0,1822},{8,0,217},{9,0,765},{9,0,766},{10,0,408},{11,0, +51},{11,0,793},{12,0,266},{15,0,158},{20,0,89},{150,0,32},{4,11,297},{6,11,529}, +{7,0,1330},{7,11,152},{7,11,713},{7,11,1845},{8,11,710},{8,11,717},{140,11,639}, +{5,0,389},{136,0,636},{134,0,1409},{4,10,562},{9,10,254},{139,10,879},{134,0,893 +},{132,10,786},{4,11,520},{135,11,575},{136,0,21},{140,0,721},{136,0,959},{7,11, +1428},{7,11,1640},{9,11,169},{9,11,182},{9,11,367},{9,11,478},{9,11,506},{9,11, +551},{9,11,648},{9,11,651},{9,11,697},{9,11,705},{9,11,725},{9,11,787},{9,11,794 +},{10,11,198},{10,11,214},{10,11,267},{10,11,275},{10,11,456},{10,11,551},{10,11 +,561},{10,11,613},{10,11,627},{10,11,668},{10,11,675},{10,11,691},{10,11,695},{ +10,11,707},{10,11,715},{11,11,183},{11,11,201},{11,11,244},{11,11,262},{11,11, +352},{11,11,439},{11,11,493},{11,11,572},{11,11,591},{11,11,608},{11,11,611},{11 +,11,646},{11,11,674},{11,11,711},{11,11,751},{11,11,761},{11,11,776},{11,11,785} +,{11,11,850},{11,11,853},{11,11,862},{11,11,865},{11,11,868},{11,11,898},{11,11, +902},{11,11,903},{11,11,910},{11,11,932},{11,11,942},{11,11,957},{11,11,967},{11 +,11,972},{12,11,148},{12,11,195},{12,11,220},{12,11,237},{12,11,318},{12,11,339} +,{12,11,393},{12,11,445},{12,11,450},{12,11,474},{12,11,509},{12,11,533},{12,11, +591},{12,11,594},{12,11,597},{12,11,621},{12,11,633},{12,11,642},{13,11,59},{13, +11,60},{13,11,145},{13,11,239},{13,11,250},{13,11,273},{13,11,329},{13,11,344},{ +13,11,365},{13,11,372},{13,11,387},{13,11,403},{13,11,414},{13,11,456},{13,11, +478},{13,11,483},{13,11,489},{14,11,55},{14,11,57},{14,11,81},{14,11,90},{14,11, +148},{14,11,239},{14,11,266},{14,11,321},{14,11,326},{14,11,327},{14,11,330},{14 +,11,347},{14,11,355},{14,11,401},{14,11,411},{14,11,414},{14,11,416},{14,11,420} +,{15,11,61},{15,11,74},{15,11,87},{15,11,88},{15,11,94},{15,11,96},{15,11,116},{ +15,11,149},{15,11,154},{16,11,50},{16,11,63},{16,11,73},{17,11,2},{17,11,66},{17 +,11,92},{17,11,103},{17,11,112},{18,11,50},{18,11,54},{18,11,82},{18,11,86},{18, +11,90},{18,11,111},{18,11,115},{18,11,156},{19,11,40},{19,11,79},{20,11,78},{149 +,11,22},{137,11,170},{134,0,1433},{135,11,1307},{139,11,411},{5,0,189},{7,0,442} +,{7,0,443},{8,0,281},{12,0,174},{141,0,261},{6,10,216},{7,10,901},{7,10,1343},{ +136,10,493},{5,11,397},{6,11,154},{7,10,341},{7,11,676},{8,11,443},{8,11,609},{9 +,11,24},{9,11,325},{10,11,35},{11,10,219},{11,11,535},{11,11,672},{11,11,1018},{ +12,11,637},{144,11,30},{6,0,2},{7,0,191},{7,0,446},{7,0,1262},{7,0,1737},{8,0,22 +},{8,0,270},{8,0,612},{9,0,4},{9,0,312},{9,0,436},{9,0,626},{10,0,216},{10,0,311 +},{10,0,521},{10,0,623},{11,0,72},{11,0,330},{11,0,455},{12,0,321},{12,0,504},{ +12,0,530},{12,0,543},{13,0,17},{13,0,156},{13,0,334},{14,0,131},{17,0,60},{148,0 +,64},{7,0,354},{10,0,410},{139,0,815},{139,10,130},{7,10,1734},{137,11,631},{10, +10,115},{11,10,420},{12,0,425},{13,10,404},{14,10,346},{15,0,112},{143,10,54},{6 +,0,60},{6,0,166},{7,0,374},{7,0,670},{7,0,1327},{8,0,411},{8,0,435},{9,0,653},{9 +,0,740},{10,0,385},{11,0,222},{11,0,324},{11,0,829},{140,0,611},{7,0,1611},{13,0 +,14},{15,0,44},{19,0,13},{148,0,76},{133,11,981},{4,11,56},{7,11,1791},{8,11,607 +},{8,11,651},{11,11,465},{11,11,835},{12,11,337},{141,11,480},{5,10,1011},{6,0, +1478},{136,10,701},{139,0,596},{5,0,206},{134,0,398},{4,10,54},{5,10,666},{7,10, +1039},{7,10,1130},{9,10,195},{138,10,302},{7,0,50},{9,11,158},{138,11,411},{135, +11,1120},{6,0,517},{6,10,1669},{7,0,1159},{10,0,621},{139,0,192},{4,0,592},{6,0, +600},{135,0,1653},{10,0,223},{139,0,645},{136,11,139},{7,0,64},{136,0,245},{142, +0,278},{6,11,622},{135,11,1030},{136,0,604},{134,0,1502},{138,0,265},{141,11,168 +},{7,0,1763},{140,0,310},{7,10,798},{139,11,719},{7,11,160},{10,11,624},{142,11, +279},{132,11,363},{7,10,122},{9,10,259},{10,10,84},{11,10,470},{12,10,541},{141, +10,379},{5,0,129},{6,0,61},{135,0,947},{134,0,1356},{135,11,1191},{13,0,505},{ +141,0,506},{5,10,82},{5,10,131},{7,10,1755},{8,10,31},{9,10,168},{9,10,764},{11, +0,1000},{139,10,869},{134,0,966},{134,10,605},{134,11,292},{5,11,177},{6,11,616} +,{7,11,827},{9,11,525},{138,11,656},{135,11,1486},{138,11,31},{5,10,278},{137,10 +,68},{4,10,163},{5,10,201},{5,10,307},{5,10,310},{6,10,335},{7,10,284},{136,10, +165},{6,0,839},{135,10,1660},{136,10,781},{6,10,33},{135,10,1244},{133,0,637},{4 +,11,161},{133,11,631},{137,0,590},{7,10,1953},{136,10,720},{5,0,280},{7,0,1226}, +{138,10,203},{134,0,1386},{5,0,281},{6,0,1026},{6,10,326},{7,10,677},{137,10,425 +},{7,11,1557},{135,11,1684},{135,0,1064},{9,11,469},{9,11,709},{12,11,512},{14, +11,65},{145,11,12},{134,0,917},{10,11,229},{11,11,73},{11,11,376},{139,11,433},{ +7,0,555},{7,10,1316},{7,10,1412},{7,10,1839},{9,0,192},{9,10,589},{11,10,241},{ +11,10,676},{11,10,811},{11,10,891},{12,10,140},{12,10,346},{12,10,479},{13,0,30} +,{13,0,49},{13,10,381},{14,10,188},{15,0,150},{16,0,76},{18,10,30},{148,0,52},{ +149,0,15},{6,0,1882},{6,0,1883},{6,0,1897},{9,0,945},{9,0,1014},{9,0,1020},{12,0 +,823},{12,0,842},{12,0,866},{12,0,934},{15,0,242},{146,0,208},{6,0,965},{134,0, +1499},{7,0,33},{7,0,120},{8,0,489},{9,0,319},{10,0,820},{11,0,1004},{12,0,379},{ +12,0,679},{13,0,117},{13,0,412},{14,0,25},{15,0,52},{15,0,161},{16,0,47},{149,0, +2},{6,11,558},{7,11,651},{8,11,421},{9,11,0},{138,11,34},{4,0,937},{5,0,801},{5, +10,358},{7,0,473},{7,10,1184},{10,10,662},{13,10,212},{13,10,304},{13,10,333},{ +145,10,98},{132,0,877},{6,0,693},{134,0,824},{132,0,365},{7,11,1832},{138,11,374 +},{5,0,7},{139,0,774},{4,0,734},{5,0,662},{134,0,430},{4,0,746},{135,0,1090},{5, +0,360},{8,0,237},{10,0,231},{147,0,124},{138,11,348},{6,11,6},{7,11,81},{7,11, +771},{7,11,1731},{9,11,405},{138,11,421},{6,0,740},{137,0,822},{133,10,946},{7,0 +,1485},{136,0,929},{7,10,411},{8,10,631},{9,10,323},{10,10,355},{11,10,491},{12, +10,143},{12,10,402},{13,10,73},{14,10,408},{15,10,107},{146,10,71},{135,10,590}, +{5,11,881},{133,11,885},{150,11,25},{4,0,852},{5,11,142},{134,11,546},{7,10,1467 +},{8,10,328},{10,10,544},{11,10,955},{13,10,320},{145,10,83},{9,0,17},{10,0,291} +,{11,10,511},{13,10,394},{14,10,298},{14,10,318},{146,10,103},{5,11,466},{11,11, +571},{12,11,198},{13,11,283},{14,11,186},{15,11,21},{143,11,103},{134,0,1001},{4 +,11,185},{5,11,257},{5,11,839},{5,11,936},{7,11,171},{9,11,399},{10,11,258},{10, +11,395},{10,11,734},{11,11,1014},{12,11,23},{13,11,350},{14,11,150},{147,11,6},{ +143,0,35},{132,0,831},{5,10,835},{134,10,483},{4,0,277},{5,0,608},{6,0,493},{7,0 +,457},{7,11,404},{7,11,1377},{7,11,1430},{7,11,2017},{8,11,149},{8,11,239},{8,11 +,512},{8,11,793},{8,11,818},{9,11,474},{9,11,595},{10,11,122},{10,11,565},{10,11 +,649},{10,11,783},{11,11,239},{11,11,295},{11,11,447},{11,11,528},{11,11,639},{ +11,11,800},{11,11,936},{12,0,384},{12,11,25},{12,11,73},{12,11,77},{12,11,157},{ +12,11,316},{12,11,390},{12,11,391},{12,11,394},{12,11,395},{12,11,478},{12,11, +503},{12,11,592},{12,11,680},{13,11,50},{13,11,53},{13,11,132},{13,11,198},{13, +11,275},{13,11,322},{13,11,415},{14,11,71},{14,11,257},{14,11,395},{15,11,71},{ +15,11,136},{17,11,123},{18,11,93},{147,11,58},{134,0,1351},{7,0,27},{135,0,316}, +{136,11,712},{136,0,984},{133,0,552},{137,0,264},{132,0,401},{6,0,710},{6,0,1111 +},{134,0,1343},{134,0,1211},{9,0,543},{10,0,524},{11,0,108},{11,0,653},{12,0,524 +},{13,0,123},{14,0,252},{16,0,18},{19,0,38},{20,0,26},{20,0,65},{21,0,3},{151,0, +11},{4,0,205},{5,0,623},{7,0,104},{8,0,519},{137,0,716},{132,10,677},{4,11,377}, +{152,11,13},{135,11,1673},{7,0,579},{9,0,41},{9,0,244},{9,0,669},{10,0,5},{11,0, +861},{11,0,951},{139,0,980},{132,0,717},{136,0,1011},{132,0,805},{4,11,180},{135 +,11,1906},{132,10,777},{132,10,331},{132,0,489},{4,11,491},{5,10,747},{134,0, +1024},{135,11,1182},{4,11,171},{138,11,234},{4,11,586},{7,11,1186},{138,11,631}, +{135,0,892},{135,11,336},{9,11,931},{10,11,334},{148,11,71},{137,0,473},{6,0,864 +},{11,11,926},{140,0,659},{7,0,819},{9,0,26},{9,0,392},{10,0,152},{10,0,226},{11 +,0,19},{12,0,276},{12,0,426},{12,0,589},{13,0,460},{15,0,97},{19,0,48},{148,0, +104},{135,0,51},{133,10,326},{4,10,691},{146,10,16},{9,0,130},{10,10,680},{10,10 +,793},{11,0,765},{141,10,357},{133,11,765},{6,10,32},{7,10,385},{7,10,757},{7,10 +,1916},{8,0,229},{8,10,94},{8,10,711},{9,10,541},{10,10,162},{10,10,795},{11,10, +989},{11,10,1010},{12,10,14},{142,10,308},{7,11,474},{137,11,578},{132,0,674},{ +132,0,770},{5,0,79},{7,0,1027},{7,0,1477},{139,0,52},{133,11,424},{134,0,1666},{ +6,0,409},{6,10,349},{6,10,1682},{7,10,1252},{8,10,112},{8,11,714},{9,10,435},{9, +10,668},{10,10,290},{10,10,319},{10,10,815},{11,10,180},{11,10,837},{12,10,240}, +{13,10,152},{13,10,219},{142,10,158},{5,0,789},{134,0,195},{4,0,251},{4,0,688},{ +7,0,513},{135,0,1284},{132,10,581},{9,11,420},{10,11,269},{10,11,285},{10,11,576 +},{11,11,397},{13,11,175},{145,11,90},{6,10,126},{7,10,573},{8,10,397},{142,10, +44},{132,11,429},{133,0,889},{4,0,160},{5,0,330},{7,0,1434},{136,0,174},{7,11,18 +},{7,11,699},{7,11,1966},{8,11,752},{9,11,273},{9,11,412},{9,11,703},{10,11,71}, +{10,11,427},{10,11,508},{146,11,97},{6,0,872},{134,0,899},{133,10,926},{134,0, +1126},{134,0,918},{4,11,53},{5,11,186},{135,11,752},{7,0,268},{136,0,569},{134,0 +,1224},{6,0,1361},{7,10,1232},{137,10,531},{8,11,575},{10,11,289},{139,11,319},{ +133,10,670},{132,11,675},{133,0,374},{135,10,1957},{133,0,731},{11,0,190},{11,11 +,190},{15,0,49},{143,11,49},{4,0,626},{5,0,506},{5,0,642},{6,0,425},{10,0,202},{ +139,0,141},{137,0,444},{7,10,242},{135,10,1942},{6,11,209},{8,11,468},{9,11,210} +,{11,11,36},{12,11,28},{12,11,630},{13,11,21},{13,11,349},{14,11,7},{145,11,13}, +{4,11,342},{135,11,1179},{5,10,834},{7,10,1202},{8,10,14},{9,10,481},{137,10,880 +},{4,11,928},{133,11,910},{4,11,318},{4,11,496},{7,11,856},{139,11,654},{136,0, +835},{7,0,1526},{138,10,465},{151,0,17},{135,0,477},{4,10,357},{6,10,172},{7,10, +143},{137,10,413},{6,0,1374},{138,0,994},{4,10,590},{146,0,76},{7,0,287},{8,0, +355},{9,0,293},{137,0,743},{134,0,1389},{7,11,915},{8,11,247},{147,11,0},{4,11, +202},{5,11,382},{6,11,454},{7,11,936},{7,11,1803},{8,11,758},{9,11,375},{9,11, +895},{10,11,743},{10,11,792},{11,11,978},{11,11,1012},{142,11,109},{5,0,384},{8, +0,455},{140,0,48},{132,11,390},{5,10,169},{7,10,333},{136,10,45},{5,0,264},{134, +0,184},{138,11,791},{133,11,717},{132,10,198},{6,11,445},{7,11,332},{137,11,909} +,{136,0,1001},{4,10,24},{5,10,140},{5,10,185},{7,10,1500},{11,10,565},{139,10, +838},{134,11,578},{5,0,633},{6,0,28},{135,0,1323},{132,0,851},{136,11,267},{7,0, +359},{8,0,243},{140,0,175},{4,10,334},{133,10,593},{141,11,87},{136,11,766},{10, +0,287},{10,11,287},{12,0,138},{140,11,138},{4,0,105},{132,0,740},{140,10,116},{ +134,0,857},{135,11,1841},{6,0,1402},{137,0,819},{132,11,584},{132,10,709},{133, +10,897},{5,0,224},{13,0,174},{146,0,52},{135,10,1840},{4,10,608},{133,10,497},{ +139,11,60},{4,0,758},{135,0,1649},{4,11,226},{4,11,326},{135,11,1770},{5,11,426} +,{8,11,30},{9,11,2},{11,11,549},{147,11,122},{135,10,2039},{6,10,540},{136,10, +136},{4,0,573},{4,10,897},{5,10,786},{136,0,655},{7,0,351},{139,0,128},{133,10, +999},{4,10,299},{135,10,1004},{133,0,918},{132,11,345},{4,11,385},{7,11,265},{ +135,11,587},{133,10,456},{136,10,180},{6,0,687},{134,0,1537},{4,11,347},{5,11, +423},{5,11,996},{135,11,1329},{132,10,755},{7,11,1259},{9,11,125},{11,11,65},{ +140,11,285},{5,11,136},{6,11,136},{136,11,644},{134,0,1525},{4,0,1009},{135,0, +1139},{139,10,338},{132,0,340},{135,10,1464},{8,0,847},{10,0,861},{10,0,876},{10 +,0,889},{10,0,922},{10,0,929},{10,0,933},{12,0,784},{140,0,791},{139,0,176},{9, +11,134},{10,11,2},{10,11,27},{10,11,333},{11,11,722},{143,11,1},{4,11,433},{133, +11,719},{5,0,985},{7,0,509},{7,0,529},{145,0,96},{132,0,615},{4,10,890},{5,10, +805},{5,10,819},{5,10,961},{6,10,396},{6,10,1631},{6,10,1678},{7,10,1967},{7,10, +2041},{9,10,630},{11,10,8},{11,10,1019},{12,10,176},{13,10,225},{14,10,292},{149 +,10,24},{135,0,1919},{134,0,1131},{144,11,21},{144,11,51},{135,10,1815},{4,0,247 +},{7,10,1505},{10,10,190},{10,10,634},{11,10,792},{12,10,358},{140,10,447},{5,10 +,0},{6,10,536},{7,10,604},{13,10,445},{145,10,126},{4,0,184},{5,0,390},{6,0,337} +,{7,0,23},{7,0,494},{7,0,618},{7,0,1456},{8,0,27},{8,0,599},{10,0,153},{139,0, +710},{6,10,232},{6,10,412},{7,10,1074},{8,10,9},{8,10,157},{8,10,786},{9,10,196} +,{9,10,352},{9,10,457},{10,10,337},{11,10,232},{11,10,877},{12,10,480},{140,10, +546},{7,10,958},{141,0,38},{4,10,382},{136,10,579},{4,10,212},{135,10,1206},{4, +11,555},{8,11,536},{138,11,288},{11,11,139},{139,11,171},{9,11,370},{138,11,90}, +{132,0,1015},{134,0,1088},{5,10,655},{135,11,977},{134,0,1585},{17,10,67},{147, +10,74},{10,0,227},{11,0,497},{11,0,709},{140,0,415},{6,0,360},{7,0,1664},{136,0, +478},{6,10,231},{7,0,95},{136,10,423},{140,11,65},{4,11,257},{135,11,2031},{135, +11,1768},{133,10,300},{139,11,211},{136,0,699},{6,10,237},{7,10,611},{8,10,100}, +{9,10,416},{11,10,335},{12,10,173},{146,10,101},{14,0,26},{146,0,150},{6,0,581}, +{135,0,1119},{135,10,1208},{132,0,739},{6,11,83},{6,11,1733},{135,11,1389},{137, +0,869},{4,0,67},{5,0,422},{7,0,1037},{7,0,1289},{7,0,1555},{9,0,741},{145,0,108} +,{133,10,199},{12,10,427},{146,10,38},{136,0,464},{142,0,42},{8,11,501},{9,11, +696},{138,0,96},{134,11,592},{4,0,512},{4,0,966},{5,0,342},{6,0,1855},{8,0,869}, +{8,0,875},{8,0,901},{144,0,26},{8,0,203},{11,0,823},{11,0,846},{12,0,482},{13,0, +277},{13,0,302},{13,0,464},{14,0,205},{142,0,221},{4,0,449},{133,0,718},{7,11, +1718},{9,11,95},{9,11,274},{10,11,279},{10,11,317},{10,11,420},{11,11,303},{11, +11,808},{12,11,134},{12,11,367},{13,11,149},{13,11,347},{14,11,349},{14,11,406}, +{18,11,22},{18,11,89},{18,11,122},{147,11,47},{133,11,26},{4,0,355},{6,0,311},{9 +,0,256},{138,0,404},{132,11,550},{6,10,312},{6,10,1715},{10,0,758},{10,10,584},{ +11,10,546},{11,10,692},{12,10,259},{12,10,295},{13,10,46},{141,10,154},{136,11, +822},{4,11,902},{5,0,827},{5,11,809},{6,11,122},{135,11,896},{5,0,64},{140,0,581 +},{4,0,442},{6,0,739},{7,0,1047},{7,0,1352},{7,0,1643},{7,11,1911},{9,11,449},{ +10,11,192},{138,11,740},{135,11,262},{132,10,588},{133,11,620},{4,11,34},{5,0, +977},{5,11,574},{6,0,288},{7,0,528},{7,11,279},{7,11,1624},{136,11,601},{4,10, +231},{5,10,61},{6,0,1375},{6,10,104},{7,10,729},{7,10,964},{7,10,1658},{140,10, +414},{6,10,263},{138,10,757},{132,10,320},{4,0,254},{5,11,332},{7,0,1309},{135, +11,1309},{6,11,261},{8,11,182},{139,11,943},{132,10,225},{6,0,12},{135,0,1219},{ +4,0,275},{6,11,1721},{12,0,376},{141,11,490},{4,11,933},{133,11,880},{4,10,405}, +{6,0,951},{6,0,1109},{6,0,1181},{7,0,154},{7,10,817},{14,10,58},{17,10,37},{146, +10,124},{5,10,974},{134,0,1520},{134,0,1753},{6,0,369},{6,0,502},{7,0,1036},{8,0 +,348},{9,0,452},{10,0,26},{11,0,224},{11,0,387},{11,0,772},{12,0,95},{12,0,629}, +{13,0,195},{13,0,207},{13,0,241},{14,0,260},{14,0,270},{143,0,140},{132,0,269},{ +5,0,480},{7,0,532},{7,0,1197},{7,0,1358},{8,0,291},{11,0,349},{142,0,396},{5,10, +235},{7,10,1239},{11,10,131},{140,10,370},{7,10,956},{7,10,1157},{7,10,1506},{7, +10,1606},{7,10,1615},{7,10,1619},{7,10,1736},{7,10,1775},{8,10,590},{9,10,324},{ +9,10,736},{9,10,774},{9,10,776},{9,10,784},{10,10,567},{10,10,708},{11,10,518},{ +11,10,613},{11,10,695},{11,10,716},{11,10,739},{11,10,770},{11,10,771},{11,10, +848},{11,10,857},{11,10,931},{11,10,947},{12,10,326},{12,10,387},{12,10,484},{12 +,10,528},{12,10,552},{12,10,613},{13,10,189},{13,10,256},{13,10,340},{13,10,432} +,{13,10,436},{13,10,440},{13,10,454},{14,10,174},{14,10,220},{14,10,284},{14,10, +390},{145,10,121},{8,11,598},{9,11,664},{138,11,441},{9,10,137},{138,10,221},{ +133,11,812},{148,0,15},{134,0,1341},{4,11,137},{6,0,1017},{7,11,1178},{135,11, +1520},{7,10,390},{138,10,140},{7,11,1260},{135,11,1790},{137,11,191},{135,10, +1144},{6,0,1810},{7,0,657},{8,0,886},{10,0,857},{14,0,440},{144,0,96},{6,11,1661 +},{7,11,1975},{7,11,2009},{7,11,2011},{136,0,533},{6,0,1453},{134,10,464},{132, +11,715},{5,10,407},{11,10,204},{11,10,243},{11,10,489},{12,10,293},{19,10,37},{ +20,10,73},{150,10,38},{133,11,703},{4,0,211},{5,10,325},{7,0,1483},{8,10,5},{8, +10,227},{9,10,105},{10,10,585},{140,10,614},{4,0,332},{5,0,335},{6,0,238},{7,0, +269},{7,0,811},{7,0,1797},{8,0,836},{9,0,507},{141,0,242},{5,11,89},{7,11,1915}, +{9,11,185},{9,11,235},{9,11,496},{10,11,64},{10,11,270},{10,11,403},{10,11,469}, +{10,11,529},{10,11,590},{11,11,140},{11,11,860},{13,11,1},{13,11,422},{14,11,341 +},{14,11,364},{17,11,93},{18,11,113},{19,11,97},{147,11,113},{133,11,695},{5,11, +6},{6,10,621},{6,11,183},{7,11,680},{7,11,978},{7,11,1013},{7,11,1055},{12,11, +230},{13,10,504},{13,11,172},{16,0,19},{146,11,29},{136,0,156},{133,0,1009},{6, +11,29},{139,11,63},{134,0,820},{134,10,218},{7,10,454},{7,10,782},{8,10,768},{ +140,10,686},{5,0,228},{6,0,203},{7,0,156},{8,0,347},{9,0,265},{15,11,8},{18,0,39 +},{18,11,39},{20,0,54},{20,11,54},{21,0,31},{21,11,31},{22,0,3},{22,11,3},{23,0, +0},{151,11,0},{7,0,1131},{135,0,1468},{144,10,0},{134,0,1276},{10,10,676},{140, +10,462},{132,11,311},{134,11,1740},{7,11,170},{8,11,90},{8,11,177},{8,11,415},{ +11,11,714},{142,11,281},{134,10,164},{6,0,1792},{138,0,849},{150,10,50},{5,0,291 +},{5,0,318},{7,0,765},{8,11,522},{9,0,389},{12,0,548},{142,11,328},{11,11,91},{ +13,11,129},{15,11,101},{145,11,125},{4,11,494},{6,11,74},{7,11,44},{7,11,407},{8 +,11,551},{12,11,17},{15,11,5},{148,11,11},{4,11,276},{133,11,296},{6,10,343},{7, +10,195},{7,11,1777},{9,10,226},{10,10,197},{10,10,575},{11,10,502},{139,10,899}, +{10,0,525},{139,0,82},{4,11,7},{5,11,90},{5,11,158},{6,11,542},{7,11,221},{7,11, +1574},{9,11,490},{10,11,540},{11,11,443},{11,11,757},{142,0,453},{135,0,666},{22 +,10,29},{150,11,29},{4,0,422},{147,10,8},{5,0,355},{145,0,0},{6,0,1873},{7,11, +588},{9,0,918},{9,11,175},{138,11,530},{143,11,31},{7,10,1125},{9,10,143},{11,0, +165},{14,10,405},{150,10,21},{9,0,260},{137,0,905},{5,11,872},{6,11,57},{6,11, +479},{6,11,562},{7,11,471},{7,11,1060},{9,11,447},{9,11,454},{141,11,6},{138,11, +704},{133,0,865},{5,0,914},{134,0,1625},{133,0,234},{5,11,31},{6,11,614},{7,0, +1383},{145,11,61},{7,11,1200},{138,11,460},{6,11,424},{135,11,1866},{136,0,306}, +{5,10,959},{12,11,30},{13,11,148},{14,11,87},{14,11,182},{16,11,42},{18,11,92},{ +148,11,70},{6,0,1919},{6,0,1921},{9,0,923},{9,0,930},{9,0,941},{9,0,949},{9,0, +987},{9,0,988},{9,0,992},{12,0,802},{12,0,815},{12,0,856},{12,0,885},{12,0,893}, +{12,0,898},{12,0,919},{12,0,920},{12,0,941},{12,0,947},{15,0,183},{15,0,185},{15 +,0,189},{15,0,197},{15,0,202},{15,0,233},{15,11,156},{18,0,218},{18,0,219},{146, +0,233},{135,10,1759},{136,10,173},{5,11,13},{6,11,142},{13,0,163},{13,0,180},{18 +,0,78},{148,0,35},{134,10,266},{6,11,97},{7,11,116},{8,11,322},{8,11,755},{9,11, +548},{10,11,714},{11,11,884},{141,11,324},{135,0,1312},{9,0,814},{137,11,676},{ +133,0,707},{135,0,1493},{6,0,421},{7,0,61},{7,0,1540},{10,0,11},{138,0,501},{7, +11,866},{7,11,1163},{12,0,733},{140,0,766},{137,0,341},{142,0,98},{145,11,115},{ +135,11,1111},{136,10,300},{136,0,1014},{8,11,1},{9,11,112},{138,11,326},{132,11, +730},{5,11,488},{6,11,527},{7,11,489},{7,11,1636},{8,11,121},{8,11,144},{8,11, +359},{9,11,193},{9,11,241},{9,11,336},{9,11,882},{11,11,266},{11,11,372},{11,11, +944},{12,11,401},{140,11,641},{6,0,971},{134,0,1121},{6,0,102},{7,0,72},{15,0, +142},{147,0,67},{151,0,30},{135,0,823},{134,0,1045},{5,10,427},{5,10,734},{7,10, +478},{136,10,52},{7,0,1930},{11,10,217},{142,10,165},{6,0,1512},{135,0,1870},{9, +11,31},{10,11,244},{10,11,699},{12,11,149},{141,11,497},{133,11,377},{145,11,101 +},{10,11,158},{13,11,13},{13,11,137},{13,11,258},{14,11,111},{14,11,225},{14,11, +253},{14,11,304},{14,11,339},{14,11,417},{146,11,33},{6,0,87},{6,10,1734},{7,10, +20},{7,10,1056},{8,10,732},{9,10,406},{9,10,911},{138,10,694},{134,0,1243},{137, +0,245},{7,0,68},{8,0,48},{8,0,88},{8,0,582},{8,0,681},{9,0,373},{9,0,864},{11,0, +157},{11,0,336},{11,0,843},{148,0,27},{8,11,663},{144,11,8},{133,10,613},{4,0,88 +},{5,0,137},{5,0,174},{5,0,777},{6,0,1664},{6,0,1725},{7,0,77},{7,0,426},{7,0, +1317},{7,0,1355},{8,0,126},{8,0,563},{9,0,523},{9,0,750},{10,0,310},{10,0,836},{ +11,0,42},{11,0,318},{11,0,731},{12,0,68},{12,0,92},{12,0,507},{12,0,692},{13,0, +81},{13,0,238},{13,0,374},{14,0,436},{18,0,138},{19,0,78},{19,0,111},{20,0,55},{ +20,0,77},{148,0,92},{141,0,418},{4,0,938},{137,0,625},{138,0,351},{5,11,843},{7, +10,32},{7,10,984},{8,10,85},{8,10,709},{9,10,579},{9,10,847},{9,10,856},{10,10, +799},{11,10,258},{11,10,1007},{12,10,331},{12,10,615},{13,10,188},{13,10,435},{ +14,10,8},{15,10,165},{16,10,27},{148,10,40},{6,0,1668},{7,0,1499},{8,0,117},{9,0 +,314},{138,0,174},{135,0,707},{132,11,554},{133,11,536},{5,0,403},{5,11,207},{9, +11,79},{11,11,625},{145,11,7},{132,11,424},{136,11,785},{4,10,167},{135,10,82},{ +9,0,7},{9,11,7},{23,0,6},{151,11,6},{5,10,62},{6,0,282},{6,10,534},{7,10,74},{7, +10,678},{7,10,684},{7,10,1043},{7,10,1072},{8,10,280},{8,10,541},{8,10,686},{9, +10,258},{10,10,519},{11,10,252},{140,10,282},{138,10,33},{132,10,359},{4,0,44},{ +5,0,311},{6,0,156},{7,0,639},{7,0,762},{7,0,1827},{9,0,8},{9,0,462},{148,0,83},{ +7,11,769},{9,11,18},{138,11,358},{4,0,346},{4,11,896},{6,11,1777},{7,0,115},{9,0 +,180},{9,0,456},{138,0,363},{133,10,211},{7,0,761},{7,0,1051},{137,0,545},{6,10, +145},{141,10,336},{7,11,750},{9,11,223},{11,11,27},{11,11,466},{12,11,624},{14, +11,265},{146,11,61},{6,0,752},{6,0,768},{6,0,1195},{6,0,1254},{6,0,1619},{137,0, +835},{6,0,1936},{8,0,930},{136,0,960},{132,10,263},{132,11,249},{4,10,916},{140, +0,653},{4,11,603},{133,11,661},{4,11,11},{6,11,128},{7,11,231},{7,11,1533},{8,0, +344},{138,11,725},{134,0,1483},{134,0,875},{6,0,185},{7,0,1899},{9,0,875},{139,0 +,673},{15,10,155},{144,10,79},{4,10,599},{6,10,1634},{7,0,93},{7,0,210},{7,0, +1223},{7,10,67},{7,10,691},{7,10,979},{7,10,1697},{8,0,451},{8,0,460},{8,10,207} +,{8,10,214},{8,10,231},{8,10,294},{8,10,336},{8,10,428},{8,10,471},{8,10,622},{8 +,10,626},{8,10,679},{8,10,759},{8,10,829},{9,10,11},{9,10,246},{9,10,484},{9,10, +573},{9,10,706},{9,10,762},{9,10,798},{9,10,855},{9,10,870},{9,10,912},{10,10, +303},{10,10,335},{10,10,424},{10,10,461},{10,10,543},{10,10,759},{10,10,814},{11 +,0,353},{11,0,475},{11,10,59},{11,10,235},{11,10,590},{11,10,929},{11,10,963},{ +11,10,987},{12,10,114},{12,10,182},{12,10,226},{12,10,332},{12,10,439},{12,10, +575},{12,10,598},{12,10,675},{13,10,8},{13,10,125},{13,10,194},{13,10,287},{14, +10,197},{14,10,383},{15,10,53},{17,10,63},{19,10,46},{19,10,98},{19,10,106},{148 +,10,85},{132,11,476},{4,0,327},{5,0,478},{7,0,1332},{136,0,753},{5,0,1020},{133, +0,1022},{135,11,1807},{4,0,103},{133,0,401},{4,0,499},{135,0,1421},{10,0,207},{ +13,0,164},{147,10,126},{9,11,20},{10,11,324},{139,11,488},{132,0,96},{9,11,280}, +{138,11,134},{135,0,968},{133,10,187},{135,10,1286},{5,11,112},{6,11,103},{134, +11,150},{4,10,215},{8,0,914},{9,10,38},{10,0,3},{11,10,23},{11,10,127},{139,10, +796},{135,0,399},{6,0,563},{137,0,224},{6,0,704},{134,0,1214},{4,11,708},{8,11, +15},{9,11,50},{9,11,386},{11,11,18},{11,11,529},{140,11,228},{4,11,563},{7,11, +109},{7,11,592},{7,11,637},{7,11,770},{7,11,1701},{8,11,436},{8,11,463},{9,11,60 +},{9,11,335},{9,11,904},{10,11,73},{11,11,434},{12,11,585},{13,11,331},{18,11, +110},{148,11,60},{134,0,1559},{132,11,502},{6,11,347},{138,11,161},{4,11,33},{5, +11,102},{5,11,500},{6,11,284},{7,11,1079},{7,11,1423},{7,11,1702},{8,11,470},{9, +11,554},{9,11,723},{139,11,333},{7,11,246},{135,11,840},{6,11,10},{8,11,571},{9, +11,739},{143,11,91},{5,11,626},{8,0,861},{10,0,905},{12,0,730},{140,0,789},{134, +0,946},{5,0,746},{12,0,333},{12,11,333},{14,0,332},{142,11,332},{5,11,18},{6,11, +526},{13,11,24},{13,11,110},{19,11,5},{147,11,44},{4,0,910},{5,0,832},{135,10, +2002},{10,11,768},{139,11,787},{4,11,309},{5,11,462},{7,11,970},{135,11,1097},{4 +,10,28},{5,10,440},{7,10,248},{11,10,833},{140,10,344},{134,10,1654},{6,0,632},{ +6,0,652},{6,0,1272},{6,0,1384},{134,0,1560},{134,11,1704},{5,10,853},{134,0,1393 +},{6,10,249},{7,10,1234},{139,10,573},{5,11,86},{7,11,743},{9,11,85},{10,11,281} +,{10,11,432},{11,11,490},{12,11,251},{13,11,118},{14,11,378},{146,11,143},{5,11, +524},{133,11,744},{134,0,1514},{10,0,201},{142,0,319},{7,0,717},{7,10,392},{8,10 +,20},{8,10,172},{8,10,690},{9,10,383},{9,10,845},{10,0,510},{11,10,293},{11,10, +832},{11,10,920},{11,10,984},{141,10,221},{134,0,1381},{5,10,858},{133,10,992},{ +8,0,528},{137,0,348},{10,11,107},{140,11,436},{4,0,20},{133,0,616},{134,0,1251}, +{132,11,927},{10,11,123},{12,11,670},{13,11,371},{14,11,142},{146,11,94},{134,0, +1163},{7,11,1149},{137,11,156},{134,0,307},{133,11,778},{7,0,1091},{135,0,1765}, +{5,11,502},{6,10,268},{137,10,62},{8,11,196},{10,11,283},{139,11,406},{4,0,26},{ +5,0,429},{6,0,245},{7,0,704},{7,0,1379},{135,0,1474},{133,11,855},{132,0,881},{4 +,0,621},{135,11,1596},{7,11,1400},{9,11,446},{138,11,45},{6,0,736},{138,10,106}, +{133,0,542},{134,0,348},{133,0,868},{136,0,433},{135,0,1495},{138,0,771},{6,10, +613},{136,10,223},{138,0,215},{141,0,124},{136,11,391},{135,11,172},{132,10,670} +,{140,0,55},{9,10,40},{139,10,136},{7,0,62},{147,0,112},{132,0,856},{132,11,568} +,{11,10,259},{140,0,270},{8,0,572},{137,0,698},{4,11,732},{9,10,310},{137,10,682 +},{142,10,296},{134,0,939},{136,11,733},{135,11,1435},{7,10,1401},{135,10,1476}, +{4,10,296},{6,0,352},{7,10,401},{7,10,1410},{7,10,1594},{7,10,1674},{8,10,63},{8 +,10,660},{137,10,74},{4,11,428},{133,11,668},{4,10,139},{4,10,388},{140,10,188}, +{7,11,2015},{140,11,665},{132,0,647},{146,0,10},{138,0,220},{142,0,464},{132,0, +109},{134,0,1746},{4,10,747},{6,0,515},{6,11,1623},{6,11,1681},{7,10,649},{7,10, +1479},{135,10,1583},{133,10,232},{135,0,566},{137,10,887},{4,0,40},{10,0,67},{11 +,0,117},{11,0,768},{139,0,935},{132,0,801},{7,0,992},{8,0,301},{9,0,722},{12,0, +63},{13,0,29},{14,0,161},{143,0,18},{139,0,923},{6,11,1748},{8,11,715},{9,11,802 +},{10,11,46},{10,11,819},{13,11,308},{14,11,351},{14,11,363},{146,11,67},{137,11 +,745},{4,10,14},{7,0,1145},{7,10,1801},{10,10,748},{141,10,458},{4,11,63},{5,11, +347},{134,11,474},{135,0,568},{4,10,425},{7,11,577},{7,11,1432},{9,11,475},{9,11 +,505},{9,11,526},{9,11,609},{9,11,689},{9,11,726},{9,11,735},{9,11,738},{10,11, +556},{10,11,674},{10,11,684},{11,11,89},{11,11,202},{11,11,272},{11,11,380},{11, +11,415},{11,11,505},{11,11,537},{11,11,550},{11,11,562},{11,11,640},{11,11,667}, +{11,11,688},{11,11,847},{11,11,927},{11,11,930},{11,11,940},{12,11,144},{12,11, +325},{12,11,329},{12,11,389},{12,11,403},{12,11,451},{12,11,515},{12,11,604},{12 +,11,616},{12,11,626},{13,11,66},{13,11,131},{13,11,167},{13,11,236},{13,11,368}, +{13,11,411},{13,11,434},{13,11,453},{13,11,461},{13,11,474},{14,11,59},{14,11,60 +},{14,11,139},{14,11,152},{14,11,276},{14,11,353},{14,11,402},{15,11,28},{15,11, +81},{15,11,123},{15,11,152},{18,11,136},{148,11,88},{137,0,247},{135,11,1622},{9 +,11,544},{11,11,413},{144,11,25},{4,0,645},{6,10,1768},{7,0,825},{135,11,89},{ +140,0,328},{5,10,943},{134,10,1779},{134,0,1363},{5,10,245},{6,10,576},{7,10,582 +},{136,10,225},{134,0,1280},{5,11,824},{133,11,941},{7,11,440},{8,11,230},{139, +11,106},{5,0,28},{6,0,204},{10,0,320},{10,0,583},{13,0,502},{14,0,72},{14,0,274} +,{14,0,312},{14,0,344},{15,0,159},{16,0,62},{16,0,69},{17,0,30},{18,0,42},{18,0, +53},{18,0,84},{18,0,140},{19,0,68},{19,0,85},{20,0,5},{20,0,45},{20,0,101},{22,0 +,7},{150,0,20},{4,0,558},{6,0,390},{7,0,162},{7,0,689},{9,0,360},{138,0,653},{ +134,0,764},{6,0,862},{137,0,833},{5,0,856},{6,0,1672},{6,0,1757},{134,0,1781},{5 +,0,92},{10,0,736},{140,0,102},{6,0,1927},{6,0,1944},{8,0,924},{8,0,948},{10,0, +967},{138,0,978},{134,0,1479},{5,0,590},{8,0,360},{9,0,213},{138,0,63},{134,0, +1521},{6,0,709},{134,0,891},{132,10,443},{13,0,477},{14,0,120},{148,0,61},{4,11, +914},{5,11,800},{133,11,852},{10,11,54},{141,11,115},{4,11,918},{133,11,876},{ +139,11,152},{4,11,92},{133,11,274},{135,11,1901},{9,11,800},{10,11,693},{11,11, +482},{11,11,734},{139,11,789},{4,10,298},{137,0,483},{6,0,1213},{141,11,498},{ +135,11,1451},{133,11,743},{4,0,1022},{10,0,1000},{12,0,957},{12,0,980},{12,0, +1013},{14,0,481},{144,0,116},{4,11,49},{7,11,280},{7,11,1633},{8,0,503},{145,0, +29},{135,0,1712},{134,0,466},{136,11,47},{5,10,164},{7,10,121},{142,10,189},{7, +10,812},{7,10,1261},{7,10,1360},{9,10,632},{140,10,352},{139,10,556},{132,0,731} +,{5,11,272},{5,11,908},{5,11,942},{7,11,1008},{7,11,1560},{8,11,197},{9,11,47},{ +11,11,538},{139,11,742},{4,10,172},{9,10,611},{10,10,436},{12,10,673},{141,10, +255},{133,10,844},{10,0,484},{11,0,754},{12,0,457},{14,0,171},{14,0,389},{146,0, +153},{9,10,263},{10,10,147},{138,10,492},{137,11,891},{138,0,241},{133,10,537},{ +6,0,2005},{136,0,964},{137,10,842},{151,11,8},{4,11,407},{132,11,560},{135,11, +1884},{6,0,1100},{134,0,1242},{135,0,954},{5,10,230},{5,10,392},{6,10,420},{9,10 +,568},{140,10,612},{4,11,475},{11,11,35},{11,11,90},{13,11,7},{13,11,71},{13,11, +177},{142,11,422},{136,11,332},{135,0,1958},{6,0,549},{8,0,34},{8,0,283},{9,0, +165},{138,0,475},{10,0,952},{12,0,966},{140,0,994},{5,0,652},{5,0,701},{135,0, +449},{4,0,655},{7,0,850},{17,0,75},{146,0,137},{4,0,146},{5,10,41},{7,0,1618},{7 +,10,1459},{7,10,1469},{7,10,1859},{8,0,670},{9,10,549},{139,10,905},{133,10,696} +,{6,0,159},{6,0,364},{7,0,516},{137,0,518},{135,0,1439},{6,11,222},{7,11,636},{7 +,11,1620},{8,11,409},{9,11,693},{139,11,77},{13,0,151},{141,11,45},{4,10,771},{4 +,11,336},{134,0,1027},{139,11,392},{10,11,121},{11,11,175},{149,11,16},{8,0,950} +,{138,0,983},{133,10,921},{135,0,993},{6,10,180},{7,10,1137},{8,10,751},{139,10, +805},{7,0,501},{9,0,111},{10,0,141},{11,0,332},{13,0,43},{13,0,429},{14,0,130},{ +14,0,415},{145,0,102},{4,10,183},{5,11,882},{7,10,271},{11,10,824},{11,10,952},{ +13,10,278},{13,10,339},{13,10,482},{14,10,424},{148,10,99},{4,10,19},{5,10,477}, +{5,10,596},{6,10,505},{7,10,1221},{11,10,907},{12,10,209},{141,10,214},{135,10, +1215},{133,0,452},{132,11,426},{5,0,149},{136,0,233},{133,0,935},{6,11,58},{7,11 +,654},{7,11,745},{7,11,1969},{8,11,240},{8,11,675},{9,11,479},{9,11,731},{10,11, +330},{10,11,593},{10,11,817},{11,11,32},{11,11,133},{11,11,221},{145,11,68},{7, +11,102},{9,11,538},{12,0,582},{146,0,131},{136,0,801},{134,10,1645},{132,0,70},{ +6,10,92},{6,10,188},{7,10,1269},{7,10,1524},{7,10,1876},{10,10,228},{139,10,1020 +},{4,10,459},{133,10,966},{138,0,369},{12,10,330},{144,0,36},{141,11,366},{6,10, +18},{7,0,721},{7,10,932},{8,10,757},{9,10,54},{9,10,65},{9,10,844},{10,0,236},{ +10,10,113},{10,10,315},{10,10,798},{11,10,153},{12,0,204},{12,10,151},{12,10,392 +},{12,10,666},{142,10,248},{7,0,241},{8,10,548},{9,10,532},{10,0,430},{10,10,117 +},{11,10,351},{11,10,375},{143,10,23},{134,10,1742},{133,10,965},{133,11,566},{6 +,11,48},{135,11,63},{134,10,182},{10,10,65},{10,10,488},{138,10,497},{6,11,114}, +{7,11,1224},{7,11,1556},{136,11,3},{134,0,1817},{8,11,576},{137,11,267},{6,0, +1078},{144,0,16},{9,10,588},{138,10,260},{138,0,1021},{5,0,406},{134,0,2022},{ +133,11,933},{6,0,69},{135,0,117},{7,0,1830},{136,11,427},{4,0,432},{135,0,824},{ +134,10,1786},{133,0,826},{139,11,67},{133,11,759},{135,10,308},{137,0,816},{133, +0,1000},{4,0,297},{6,0,529},{7,0,152},{7,0,713},{7,0,1845},{8,0,710},{8,0,717},{ +12,0,639},{140,0,685},{7,0,423},{136,10,588},{136,10,287},{136,0,510},{134,0, +1048},{6,0,618},{7,11,56},{7,11,1989},{8,11,337},{8,11,738},{9,11,600},{10,11, +483},{12,11,37},{13,11,447},{142,11,92},{4,0,520},{135,0,575},{8,0,990},{138,0, +977},{135,11,774},{9,11,347},{11,11,24},{140,11,170},{136,11,379},{140,10,290},{ +132,11,328},{4,0,321},{134,0,569},{4,11,101},{135,11,1171},{5,11,833},{7,0,723}, +{7,0,1135},{136,11,744},{7,10,719},{8,10,809},{136,10,834},{8,0,921},{136,10,796 +},{5,10,210},{6,10,213},{7,10,60},{10,10,364},{139,10,135},{5,0,397},{5,10,607}, +{6,0,154},{7,0,676},{8,0,443},{8,0,609},{8,10,326},{8,10,490},{9,0,24},{9,0,325} +,{10,0,35},{11,0,535},{11,0,672},{11,0,1018},{12,0,637},{144,0,30},{4,10,701},{5 +,10,472},{6,11,9},{6,11,397},{7,11,53},{7,11,1742},{9,10,758},{10,11,632},{11,11 +,828},{140,11,146},{135,10,380},{135,10,1947},{148,11,109},{10,10,278},{138,11, +278},{134,0,856},{4,10,386},{7,0,139},{8,10,405},{8,10,728},{9,10,497},{11,10, +110},{11,10,360},{15,10,37},{144,10,84},{141,0,282},{133,0,981},{5,0,288},{7,10, +1452},{7,10,1480},{8,10,634},{140,10,472},{7,0,1890},{8,11,367},{10,11,760},{14, +11,79},{20,11,17},{152,11,0},{4,10,524},{136,10,810},{4,0,56},{7,0,1791},{8,0, +607},{8,0,651},{11,0,465},{11,0,835},{12,0,337},{141,0,480},{10,10,238},{141,10, +33},{11,11,417},{12,11,223},{140,11,265},{9,0,158},{10,0,411},{140,0,261},{133, +10,532},{133,10,997},{12,11,186},{12,11,292},{14,11,100},{146,11,70},{6,0,1403}, +{136,0,617},{134,0,1205},{139,0,563},{4,0,242},{134,0,333},{4,11,186},{5,11,157} +,{8,11,168},{138,11,6},{132,0,369},{133,11,875},{5,10,782},{5,10,829},{134,10, +1738},{134,0,622},{135,11,1272},{6,0,1407},{7,11,111},{136,11,581},{7,10,1823},{ +139,10,693},{7,0,160},{10,0,624},{142,0,279},{132,0,363},{10,11,589},{12,11,111} +,{13,11,260},{14,11,82},{18,11,63},{147,11,45},{7,11,1364},{7,11,1907},{141,11, +158},{4,11,404},{4,11,659},{135,11,675},{13,11,211},{14,11,133},{14,11,204},{15, +11,64},{15,11,69},{15,11,114},{16,11,10},{19,11,23},{19,11,35},{19,11,39},{19,11 +,51},{19,11,71},{19,11,75},{152,11,15},{4,10,78},{5,10,96},{5,10,182},{7,10,1724 +},{7,10,1825},{10,10,394},{10,10,471},{11,10,532},{14,10,340},{145,10,88},{135, +10,1964},{133,11,391},{11,11,887},{14,11,365},{142,11,375},{5,11,540},{6,11,1697 +},{7,11,222},{136,11,341},{134,11,78},{9,0,601},{9,0,619},{10,0,505},{10,0,732}, +{11,0,355},{140,0,139},{134,0,292},{139,0,174},{5,0,177},{6,0,616},{7,0,827},{9, +0,525},{138,0,656},{6,10,215},{7,10,1028},{7,10,1473},{7,10,1721},{9,10,424},{10 +,0,31},{138,10,779},{135,10,584},{136,11,293},{134,0,685},{135,11,1868},{133,11, +460},{6,10,67},{7,0,647},{7,10,1630},{9,10,354},{9,10,675},{10,10,830},{14,10,80 +},{145,10,80},{4,0,161},{133,0,631},{6,10,141},{7,10,225},{9,10,59},{9,10,607},{ +10,10,312},{11,10,687},{12,10,555},{13,10,373},{13,10,494},{148,10,58},{7,11,965 +},{7,11,1460},{135,11,1604},{136,10,783},{134,11,388},{4,11,511},{6,0,722},{6,0, +1267},{9,11,333},{9,11,379},{10,11,602},{11,11,441},{11,11,723},{11,11,976},{140 +,11,357},{134,0,1797},{135,0,1684},{5,11,938},{8,11,707},{9,0,469},{9,0,709},{12 +,0,512},{14,0,65},{145,0,12},{7,0,1230},{136,0,531},{10,0,229},{11,0,73},{11,0, +376},{139,0,433},{12,0,268},{12,0,640},{142,0,119},{7,10,430},{139,10,46},{6,0, +558},{7,0,651},{8,0,421},{9,0,0},{10,0,34},{139,0,1008},{5,10,602},{6,0,106},{7, +0,1786},{7,0,1821},{7,10,2018},{9,0,102},{9,0,763},{137,10,418},{5,0,65},{6,0, +416},{7,0,1720},{7,0,1924},{8,10,677},{10,0,109},{11,0,14},{11,0,70},{11,0,569}, +{11,0,735},{15,0,153},{148,0,80},{135,11,1625},{137,11,772},{136,0,595},{6,11, +469},{7,11,1709},{138,11,515},{7,0,1832},{138,0,374},{9,0,106},{9,0,163},{9,0, +296},{10,0,167},{10,0,172},{10,0,777},{139,0,16},{6,0,6},{7,0,81},{7,0,771},{7,0 +,1731},{9,0,405},{138,0,421},{4,11,500},{135,11,938},{5,11,68},{134,11,383},{5,0 +,881},{133,0,885},{6,0,854},{6,0,1132},{6,0,1495},{6,0,1526},{6,0,1533},{134,0, +1577},{4,11,337},{6,11,353},{7,11,1934},{8,11,488},{137,11,429},{7,11,236},{7,11 +,1795},{8,11,259},{9,11,135},{9,11,177},{10,11,825},{11,11,115},{11,11,370},{11, +11,405},{11,11,604},{12,11,10},{12,11,667},{12,11,669},{13,11,76},{14,11,310},{ +15,11,76},{15,11,147},{148,11,23},{5,0,142},{134,0,546},{4,11,15},{5,11,22},{6, +11,244},{7,11,40},{7,11,200},{7,11,906},{7,11,1199},{9,11,616},{10,11,716},{11, +11,635},{11,11,801},{140,11,458},{5,0,466},{7,10,329},{11,0,571},{12,0,198},{13, +0,283},{14,0,186},{15,0,21},{143,0,103},{4,0,185},{5,0,257},{5,0,839},{5,0,936}, +{7,11,1735},{9,0,399},{10,0,258},{10,0,395},{10,0,734},{11,0,1014},{12,0,23},{13 +,0,350},{14,0,150},{147,0,6},{12,11,36},{141,11,337},{5,11,598},{7,11,791},{8,11 +,108},{137,11,123},{132,10,469},{7,0,404},{7,0,1377},{7,0,1430},{7,0,2017},{8,0, +149},{8,0,239},{8,0,512},{8,0,793},{8,0,818},{9,0,474},{9,0,595},{10,0,122},{10, +0,565},{10,0,649},{10,0,783},{11,0,239},{11,0,295},{11,0,447},{11,0,528},{11,0, +639},{11,0,800},{12,0,25},{12,0,77},{12,0,157},{12,0,256},{12,0,316},{12,0,390}, +{12,0,391},{12,0,395},{12,0,478},{12,0,503},{12,0,592},{12,0,680},{13,0,50},{13, +0,53},{13,0,132},{13,0,198},{13,0,322},{13,0,415},{13,0,511},{14,0,71},{14,0,395 +},{15,0,71},{15,0,136},{17,0,123},{18,0,93},{147,0,58},{136,0,712},{134,10,1743} +,{5,10,929},{6,10,340},{8,10,376},{136,10,807},{6,0,1848},{8,0,860},{10,0,856},{ +10,0,859},{10,0,925},{10,0,941},{140,0,762},{6,0,629},{6,0,906},{9,0,810},{140,0 +,652},{5,10,218},{7,10,1610},{138,10,83},{7,10,1512},{135,10,1794},{4,0,377},{4, +11,155},{7,11,1689},{11,10,0},{16,10,78},{152,0,13},{4,11,164},{5,11,151},{5,11, +730},{5,11,741},{7,11,498},{7,11,870},{7,11,1542},{12,11,213},{14,11,36},{14,11, +391},{17,11,111},{18,11,6},{18,11,46},{18,11,151},{19,11,36},{20,11,32},{20,11, +56},{20,11,69},{20,11,102},{21,11,4},{22,11,8},{22,11,10},{22,11,14},{150,11,31} +,{5,10,571},{135,0,1842},{4,10,455},{4,11,624},{135,11,1752},{134,0,1501},{4,11, +492},{5,11,451},{6,10,161},{7,10,372},{137,10,597},{132,10,349},{4,0,180},{135,0 +,1906},{135,11,835},{141,11,70},{132,0,491},{137,10,751},{6,10,432},{139,10,322} +,{4,0,171},{138,0,234},{6,11,113},{135,11,436},{4,0,586},{7,0,1186},{138,0,631}, +{5,10,468},{10,10,325},{11,10,856},{12,10,345},{143,10,104},{5,10,223},{10,11, +592},{10,11,753},{12,11,317},{12,11,355},{12,11,465},{12,11,469},{12,11,560},{12 +,11,578},{141,11,243},{132,10,566},{135,11,520},{4,10,59},{135,10,1394},{6,10, +436},{139,10,481},{4,10,48},{5,10,271},{7,10,953},{7,11,1878},{9,0,931},{10,0, +334},{148,0,71},{5,10,610},{8,10,457},{139,0,170},{133,10,755},{6,0,1587},{135, +10,1217},{4,10,197},{149,11,26},{133,11,585},{137,11,521},{133,0,765},{133,10, +217},{139,11,586},{133,0,424},{9,11,752},{12,11,610},{13,11,431},{16,11,59},{146 +,11,109},{136,0,714},{4,11,307},{135,0,685},{9,0,420},{10,0,269},{10,0,285},{10, +0,576},{11,0,397},{13,0,175},{145,0,90},{132,0,429},{133,11,964},{9,11,463},{138 +,11,595},{7,0,18},{7,0,699},{7,0,1966},{8,0,752},{9,0,273},{9,0,412},{9,0,703},{ +10,0,71},{10,0,427},{138,0,508},{4,10,165},{7,10,1398},{135,10,1829},{4,0,53},{5 +,0,186},{7,0,752},{7,0,828},{142,0,116},{8,0,575},{10,0,289},{139,0,319},{132,0, +675},{134,0,1424},{4,11,75},{5,11,180},{6,11,500},{7,11,58},{7,11,710},{138,11, +645},{133,11,649},{6,11,276},{7,11,282},{7,11,879},{7,11,924},{8,11,459},{9,11, +599},{9,11,754},{11,11,574},{12,11,128},{12,11,494},{13,11,52},{13,11,301},{15, +11,30},{143,11,132},{6,0,647},{134,0,1095},{5,10,9},{7,10,297},{7,10,966},{140, +10,306},{132,11,200},{134,0,1334},{5,10,146},{6,10,411},{138,10,721},{6,0,209},{ +6,0,1141},{6,0,1288},{8,0,468},{9,0,210},{11,0,36},{12,0,28},{12,0,630},{13,0,21 +},{13,0,349},{14,0,7},{145,0,13},{6,10,177},{135,10,467},{4,0,342},{135,0,1179}, +{10,11,454},{140,11,324},{4,0,928},{133,0,910},{6,11,225},{7,0,1838},{137,11,211 +},{16,0,101},{20,0,115},{20,0,118},{148,0,122},{4,0,496},{135,0,856},{4,0,318},{ +7,11,718},{11,0,654},{139,11,102},{8,11,58},{9,11,724},{11,11,809},{13,11,113},{ +145,11,72},{5,10,200},{6,11,345},{135,11,1247},{8,11,767},{8,11,803},{9,11,301}, +{137,11,903},{7,0,915},{7,11,1949},{8,0,247},{8,11,674},{147,0,0},{4,0,202},{5,0 +,382},{6,0,454},{7,0,936},{7,0,1803},{8,0,758},{9,0,375},{9,0,895},{10,0,743},{ +10,0,792},{11,0,978},{11,0,1012},{142,0,109},{7,0,1150},{7,0,1425},{7,0,1453},{ +140,0,513},{134,11,259},{138,0,791},{11,0,821},{12,0,110},{12,0,153},{18,0,41},{ +150,0,19},{134,10,481},{132,0,796},{6,0,445},{8,11,254},{137,0,909},{10,0,776},{ +13,0,345},{142,0,425},{4,10,84},{7,10,1482},{10,10,76},{138,10,142},{135,11,742} +,{5,10,1015},{134,0,578},{4,10,315},{5,10,507},{6,0,1387},{135,10,1370},{4,0,438 +},{133,0,555},{136,0,766},{133,11,248},{134,10,1722},{4,11,116},{5,11,95},{5,11, +445},{7,11,1688},{8,11,29},{9,11,272},{11,11,509},{139,11,915},{135,0,541},{133, +11,543},{8,10,222},{8,10,476},{9,10,238},{11,10,516},{11,10,575},{15,10,109},{ +146,10,100},{6,0,880},{134,0,1191},{5,11,181},{136,11,41},{134,0,1506},{132,11, +681},{7,11,25},{8,11,202},{138,11,536},{139,0,983},{137,0,768},{132,0,584},{9,11 +,423},{140,11,89},{8,11,113},{9,11,877},{10,11,554},{11,11,83},{12,11,136},{147, +11,109},{7,10,706},{7,10,1058},{138,10,538},{133,11,976},{4,11,206},{135,11,746} +,{136,11,526},{140,0,737},{11,10,92},{11,10,196},{11,10,409},{11,10,450},{11,10, +666},{11,10,777},{12,10,262},{13,10,385},{13,10,393},{15,10,115},{16,10,45},{145 +,10,82},{4,0,226},{4,0,326},{4,11,319},{5,11,699},{7,0,1770},{138,11,673},{6,10, +40},{135,10,1781},{5,0,426},{8,0,30},{9,0,2},{11,0,549},{147,0,122},{6,0,1161},{ +134,0,1329},{138,10,97},{6,10,423},{7,10,665},{135,10,1210},{7,11,13},{8,11,226} +,{10,11,537},{11,11,570},{11,11,605},{11,11,799},{11,11,804},{12,11,85},{12,11, +516},{12,11,623},{13,11,112},{13,11,361},{14,11,77},{14,11,78},{17,11,28},{147, +11,110},{132,11,769},{132,11,551},{132,11,728},{147,0,117},{9,11,57},{9,11,459}, +{10,11,425},{11,11,119},{12,11,184},{12,11,371},{13,11,358},{145,11,51},{5,11, +188},{5,11,814},{8,11,10},{9,11,421},{9,11,729},{10,11,609},{139,11,689},{134,11 +,624},{135,11,298},{135,0,462},{4,0,345},{139,10,624},{136,10,574},{4,0,385},{7, +0,265},{135,0,587},{4,11,528},{134,0,808},{133,0,398},{132,10,354},{4,0,347},{5, +0,423},{5,0,996},{135,0,1329},{135,10,1558},{7,0,1259},{9,0,125},{139,0,65},{5,0 +,136},{6,0,136},{136,0,644},{5,11,104},{6,11,173},{135,11,1631},{135,0,469},{133 +,10,830},{4,0,278},{5,0,465},{135,0,1367},{7,11,810},{8,11,138},{8,11,342},{9,11 +,84},{10,11,193},{11,11,883},{140,11,359},{5,10,496},{135,10,203},{4,0,433},{133 +,0,719},{6,10,547},{134,11,95},{5,10,88},{137,10,239},{6,11,406},{10,11,409},{10 +,11,447},{11,11,44},{140,11,100},{134,0,1423},{7,10,650},{135,10,1310},{134,0, +749},{135,11,1243},{135,0,1363},{6,0,381},{7,0,645},{7,0,694},{7,10,1076},{8,0, +546},{9,10,80},{11,10,78},{11,10,421},{11,10,534},{140,10,545},{134,11,1636},{ +135,11,1344},{7,10,274},{11,10,479},{11,10,507},{140,0,277},{4,11,282},{6,0,705} +,{6,0,783},{6,0,1275},{6,0,1481},{7,11,1034},{11,11,398},{11,11,634},{12,11,1},{ +12,11,79},{12,11,544},{14,11,237},{17,11,10},{146,11,20},{134,0,453},{4,0,555},{ +4,10,497},{7,10,1584},{8,0,536},{10,0,288},{139,0,1005},{5,11,118},{5,11,499},{6 +,11,476},{7,11,600},{7,11,888},{135,11,1096},{138,0,987},{7,0,1107},{7,10,261},{ +7,10,1115},{7,10,1354},{7,10,1588},{7,10,1705},{7,10,1902},{9,10,465},{10,10,248 +},{10,10,349},{10,10,647},{11,10,527},{11,10,660},{11,10,669},{12,10,529},{141, +10,305},{7,11,296},{7,11,596},{8,11,560},{8,11,586},{9,11,612},{11,11,100},{11, +11,304},{12,11,46},{13,11,89},{14,11,112},{145,11,122},{9,0,370},{138,0,90},{136 +,10,13},{132,0,860},{7,10,642},{8,10,250},{11,10,123},{11,10,137},{13,10,48},{ +142,10,95},{135,10,1429},{137,11,321},{132,0,257},{135,0,2031},{7,0,1768},{7,11, +1599},{7,11,1723},{8,11,79},{8,11,106},{8,11,190},{8,11,302},{8,11,383},{9,11, +119},{9,11,233},{9,11,298},{9,11,419},{9,11,471},{10,11,181},{10,11,406},{11,11, +57},{11,11,85},{11,11,120},{11,11,177},{11,11,296},{11,11,382},{11,11,454},{11, +11,758},{11,11,999},{12,11,27},{12,11,98},{12,11,131},{12,11,245},{12,11,312},{ +12,11,446},{12,11,454},{13,11,25},{13,11,98},{13,11,426},{13,11,508},{14,11,6},{ +14,11,163},{14,11,272},{14,11,277},{14,11,370},{15,11,95},{15,11,138},{15,11,167 +},{17,11,18},{17,11,38},{20,11,96},{149,11,32},{5,11,722},{134,11,1759},{145,11, +16},{6,0,1071},{134,0,1561},{10,10,545},{140,10,301},{6,0,83},{6,0,1733},{135,0, +1389},{4,0,835},{135,0,1818},{133,11,258},{4,10,904},{133,10,794},{134,0,2006},{ +5,11,30},{7,11,495},{8,11,134},{9,11,788},{140,11,438},{135,11,2004},{137,0,696} +,{5,11,50},{6,11,439},{7,11,780},{135,11,1040},{7,11,772},{7,11,1104},{7,11,1647 +},{11,11,269},{11,11,539},{11,11,607},{11,11,627},{11,11,706},{11,11,975},{12,11 +,248},{12,11,311},{12,11,434},{12,11,600},{12,11,622},{13,11,297},{13,11,367},{ +13,11,485},{14,11,69},{14,11,409},{143,11,108},{5,11,1},{6,11,81},{138,11,520},{ +7,0,1718},{9,0,95},{9,0,274},{10,0,279},{10,0,317},{10,0,420},{11,0,303},{11,0, +808},{12,0,134},{12,0,367},{13,0,149},{13,0,347},{14,0,349},{14,0,406},{18,0,22} +,{18,0,89},{18,0,122},{147,0,47},{5,11,482},{8,11,98},{9,11,172},{10,11,222},{10 +,11,700},{10,11,822},{11,11,302},{11,11,778},{12,11,50},{12,11,127},{12,11,396}, +{13,11,62},{13,11,328},{14,11,122},{147,11,72},{7,10,386},{138,10,713},{6,10,7}, +{6,10,35},{7,10,147},{7,10,1069},{7,10,1568},{7,10,1575},{7,10,1917},{8,10,43},{ +8,10,208},{9,10,128},{9,10,866},{10,10,20},{11,10,981},{147,10,33},{133,0,26},{ +132,0,550},{5,11,2},{7,11,1494},{136,11,589},{6,11,512},{7,11,797},{8,11,253},{9 +,11,77},{10,11,1},{10,11,129},{10,11,225},{11,11,118},{11,11,226},{11,11,251},{ +11,11,430},{11,11,701},{11,11,974},{11,11,982},{12,11,64},{12,11,260},{12,11,488 +},{140,11,690},{7,10,893},{141,10,424},{134,0,901},{136,0,822},{4,0,902},{5,0, +809},{134,0,122},{6,0,807},{134,0,1366},{5,11,748},{6,11,553},{135,0,262},{133,0 +,620},{4,0,34},{5,0,574},{7,0,279},{7,0,1624},{136,0,601},{6,10,322},{9,0,170},{ +9,10,552},{11,10,274},{13,10,209},{13,10,499},{14,10,85},{15,10,126},{145,10,70} +,{132,0,537},{4,11,12},{7,11,420},{7,11,522},{7,11,809},{8,11,797},{141,11,88},{ +133,0,332},{8,10,83},{8,10,742},{8,10,817},{9,10,28},{9,10,29},{9,10,885},{10,10 +,387},{11,10,633},{11,10,740},{13,10,235},{13,10,254},{15,10,143},{143,10,146},{ +6,0,1909},{9,0,964},{12,0,822},{12,0,854},{12,0,865},{12,0,910},{12,0,938},{15,0 +,169},{15,0,208},{15,0,211},{18,0,205},{18,0,206},{18,0,220},{18,0,223},{152,0, +24},{140,10,49},{5,11,528},{135,11,1580},{6,0,261},{8,0,182},{139,0,943},{134,0, +1721},{4,0,933},{133,0,880},{136,11,321},{5,11,266},{9,11,290},{9,11,364},{10,11 +,293},{11,11,606},{142,11,45},{4,11,50},{6,0,1609},{6,11,510},{6,11,594},{9,11, +121},{10,11,49},{10,11,412},{139,11,834},{7,0,895},{136,11,748},{132,11,466},{4, +10,110},{10,10,415},{10,10,597},{142,10,206},{133,0,812},{135,11,281},{6,0,1890} +,{6,0,1902},{6,0,1916},{7,10,205},{7,10,2000},{9,0,929},{9,0,942},{9,0,975},{9,0 +,984},{9,0,986},{9,0,1011},{9,0,1019},{12,0,804},{12,0,851},{12,0,867},{12,0,916 +},{12,0,923},{15,0,194},{15,0,204},{15,0,210},{15,0,222},{15,0,223},{15,0,229},{ +15,0,250},{18,0,179},{18,0,186},{146,0,192},{132,11,667},{135,0,778},{4,0,137},{ +7,0,1178},{135,0,1520},{134,0,1314},{4,11,242},{134,11,333},{6,0,1661},{7,0,1975 +},{7,0,2009},{135,0,2011},{134,0,1591},{4,10,283},{135,10,1194},{11,0,820},{150, +0,51},{4,11,39},{5,11,36},{7,11,1843},{8,11,407},{11,11,144},{140,11,523},{134, +10,1720},{4,11,510},{7,11,29},{7,11,66},{7,11,1980},{10,11,487},{10,11,809},{146 +,11,9},{5,0,89},{7,0,1915},{9,0,185},{9,0,235},{10,0,64},{10,0,270},{10,0,403},{ +10,0,469},{10,0,529},{10,0,590},{11,0,140},{11,0,860},{13,0,1},{13,0,422},{14,0, +341},{14,0,364},{17,0,93},{18,0,113},{19,0,97},{147,0,113},{133,0,695},{6,0,987} +,{134,0,1160},{5,0,6},{6,0,183},{7,0,680},{7,0,978},{7,0,1013},{7,0,1055},{12,0, +230},{13,0,172},{146,0,29},{134,11,570},{132,11,787},{134,11,518},{6,0,29},{139, +0,63},{132,11,516},{136,11,821},{132,0,311},{134,0,1740},{7,0,170},{8,0,90},{8,0 +,177},{8,0,415},{8,10,735},{11,0,714},{142,0,281},{134,0,1961},{135,11,1405},{4, +11,10},{7,11,917},{139,11,786},{5,10,132},{9,10,486},{9,10,715},{10,10,458},{11, +10,373},{11,10,668},{11,10,795},{11,10,897},{12,10,272},{12,10,424},{12,10,539}, +{12,10,558},{14,10,245},{14,10,263},{14,10,264},{14,10,393},{142,10,403},{11,0, +91},{13,0,129},{15,0,101},{145,0,125},{135,0,1132},{4,0,494},{6,0,74},{7,0,44},{ +7,0,407},{12,0,17},{15,0,5},{148,0,11},{133,10,379},{5,0,270},{5,11,684},{6,10, +89},{6,10,400},{7,10,1569},{7,10,1623},{7,10,1850},{8,10,218},{8,10,422},{9,10, +570},{138,10,626},{4,0,276},{133,0,296},{6,0,1523},{134,11,27},{6,10,387},{7,10, +882},{141,10,111},{6,10,224},{7,10,877},{137,10,647},{135,10,790},{4,0,7},{5,0, +90},{5,0,158},{6,0,542},{7,0,221},{7,0,1574},{9,0,490},{10,0,540},{11,0,443},{ +139,0,757},{7,0,588},{9,0,175},{138,0,530},{135,10,394},{142,11,23},{134,0,786}, +{135,0,580},{7,0,88},{136,0,627},{5,0,872},{6,0,57},{7,0,471},{9,0,447},{137,0, +454},{6,11,342},{6,11,496},{8,11,275},{137,11,206},{4,11,909},{133,11,940},{4,11 +,891},{134,0,735},{7,10,1409},{8,0,845},{136,0,916},{5,0,31},{134,0,614},{11,0, +458},{12,0,15},{140,0,432},{8,0,330},{140,0,477},{4,0,530},{4,11,687},{5,0,521}, +{7,0,1200},{138,0,460},{6,0,424},{135,0,1866},{9,0,569},{12,0,12},{12,0,81},{12, +0,319},{13,0,69},{14,0,259},{16,0,87},{17,0,1},{17,0,21},{17,0,24},{18,0,15},{18 +,0,56},{18,0,59},{18,0,127},{18,0,154},{19,0,19},{148,0,31},{7,0,1302},{136,10, +38},{134,11,253},{5,10,261},{7,10,78},{7,10,199},{8,10,815},{9,10,126},{138,10, +342},{5,0,595},{135,0,1863},{6,11,41},{141,11,160},{5,0,13},{134,0,142},{6,0,97} +,{7,0,116},{7,11,1304},{8,0,322},{8,0,755},{9,0,548},{10,0,714},{10,11,477},{11, +0,884},{141,0,324},{132,10,628},{134,11,1718},{7,10,266},{136,10,804},{135,10, +208},{6,10,79},{7,0,1021},{135,10,1519},{7,0,1472},{135,0,1554},{6,11,362},{146, +11,51},{7,0,1071},{7,0,1541},{7,0,1767},{7,0,1806},{11,0,162},{11,0,242},{11,0, +452},{12,0,605},{15,0,26},{144,0,44},{136,10,741},{133,11,115},{145,0,115},{134, +10,376},{6,0,1406},{134,0,1543},{5,11,193},{12,11,178},{13,11,130},{145,11,84},{ +135,0,1111},{5,11,705},{8,0,1},{9,0,650},{9,11,606},{138,0,326},{5,0,488},{6,0, +527},{7,0,489},{7,0,1636},{8,0,121},{8,0,144},{8,0,359},{9,0,193},{9,0,241},{9,0 +,336},{9,0,882},{11,0,266},{11,0,372},{11,0,944},{12,0,401},{140,0,641},{135,11, +174},{6,0,267},{7,10,244},{7,10,632},{7,10,1609},{8,10,178},{8,10,638},{141,10, +58},{134,0,1983},{134,0,1155},{134,0,1575},{134,0,1438},{9,0,31},{10,0,244},{10, +0,699},{12,0,149},{141,0,497},{133,0,377},{4,11,122},{5,11,796},{5,11,952},{6,11 +,1660},{6,11,1671},{8,11,567},{9,11,687},{9,11,742},{10,11,686},{11,11,356},{11, +11,682},{140,11,281},{145,0,101},{11,11,0},{144,11,78},{5,10,791},{5,11,179},{7, +11,1095},{135,11,1213},{8,11,372},{9,11,122},{138,11,175},{7,10,686},{8,10,33},{ +8,10,238},{10,10,616},{11,10,467},{11,10,881},{13,10,217},{13,10,253},{142,10, +268},{4,11,66},{7,11,722},{7,11,904},{137,0,476},{7,11,352},{137,11,684},{135,0, +2023},{135,0,1836},{132,10,447},{5,0,843},{144,0,35},{137,11,779},{141,11,35},{4 +,10,128},{5,10,415},{6,10,462},{7,10,294},{7,10,578},{10,10,710},{139,10,86},{ +132,0,554},{133,0,536},{136,10,587},{5,0,207},{9,0,79},{11,0,625},{145,0,7},{6, +10,427},{7,0,1371},{138,10,692},{4,0,424},{4,10,195},{135,10,802},{5,11,564},{ +136,0,785},{135,0,336},{4,0,896},{6,0,1777},{134,11,556},{137,11,103},{134,10, +1683},{7,11,544},{8,11,719},{138,11,61},{138,10,472},{4,11,5},{5,11,498},{136,11 +,637},{7,0,750},{9,0,223},{11,0,27},{11,0,466},{12,0,624},{14,0,265},{146,0,61}, +{12,0,238},{12,11,238},{18,0,155},{146,11,155},{151,10,28},{133,11,927},{5,10,3} +,{8,10,578},{9,10,118},{10,10,705},{12,0,383},{141,10,279},{4,11,893},{5,11,780} +,{133,11,893},{4,0,603},{133,0,661},{4,0,11},{5,10,229},{5,11,238},{6,0,128},{7, +0,231},{7,0,1533},{7,11,1350},{138,0,725},{8,10,102},{10,10,578},{10,10,672},{12 +,10,496},{13,10,408},{14,10,121},{145,10,106},{132,0,476},{134,0,1552},{134,11, +1729},{8,10,115},{8,10,350},{9,10,489},{10,10,128},{11,10,306},{12,10,373},{14, +10,30},{17,10,79},{19,10,80},{150,10,55},{135,0,1807},{4,0,680},{4,11,60},{7,11, +760},{7,11,1800},{8,11,314},{9,11,700},{139,11,487},{4,10,230},{5,10,702},{148, +11,94},{132,11,228},{139,0,435},{9,0,20},{10,0,324},{10,0,807},{139,0,488},{6,10 +,1728},{136,11,419},{4,10,484},{18,10,26},{19,10,42},{20,10,43},{21,10,0},{23,10 +,27},{152,10,14},{135,0,1431},{133,11,828},{5,0,112},{6,0,103},{6,0,150},{7,0, +1303},{7,11,176},{7,11,178},{7,11,1110},{9,0,292},{10,0,481},{10,11,481},{20,0, +13},{148,11,13},{138,0,356},{4,11,51},{5,11,39},{6,11,4},{7,11,591},{7,11,849},{ +7,11,951},{7,11,1129},{7,11,1613},{7,11,1760},{7,11,1988},{9,11,434},{10,11,754} +,{11,11,25},{11,11,37},{139,11,414},{6,0,1963},{134,0,2000},{132,10,633},{5,11, +902},{134,0,1244},{135,11,928},{140,0,18},{138,0,204},{135,11,1173},{134,0,867}, +{4,0,708},{8,0,15},{9,0,50},{9,0,386},{11,0,18},{11,0,529},{140,0,228},{134,11, +270},{4,0,563},{7,0,109},{7,0,592},{7,0,637},{7,0,770},{8,0,463},{9,0,60},{9,0, +335},{9,0,904},{10,0,73},{11,0,434},{12,0,585},{13,0,331},{18,0,110},{148,0,60}, +{132,0,502},{14,11,359},{19,11,52},{148,11,47},{6,11,377},{7,11,1025},{9,11,613} +,{145,11,104},{5,10,70},{5,10,622},{6,0,347},{6,10,334},{7,10,1032},{9,10,171},{ +10,0,161},{11,10,26},{11,10,213},{11,10,637},{11,10,707},{12,10,202},{12,10,380} +,{13,10,226},{13,10,355},{14,10,222},{145,10,42},{132,11,416},{4,0,33},{5,0,102} +,{6,0,284},{7,0,1079},{7,0,1423},{7,0,1702},{8,0,470},{9,0,554},{9,0,723},{11,0, +333},{142,11,372},{5,11,152},{5,11,197},{7,11,340},{7,11,867},{10,11,548},{10,11 +,581},{11,11,6},{12,11,3},{12,11,19},{14,11,110},{142,11,289},{7,0,246},{135,0, +840},{6,0,10},{8,0,571},{9,0,739},{143,0,91},{4,10,23},{4,10,141},{5,10,313},{5, +10,1014},{6,0,465},{6,10,50},{7,0,1465},{7,10,142},{7,10,559},{8,10,640},{9,10, +460},{9,10,783},{11,10,741},{12,10,183},{141,10,488},{133,0,626},{136,0,614},{ +138,0,237},{7,11,34},{7,11,190},{8,11,28},{8,11,141},{8,11,444},{8,11,811},{9,11 +,468},{11,11,334},{12,11,24},{12,11,386},{140,11,576},{133,11,757},{5,0,18},{6,0 +,526},{13,0,24},{13,0,110},{19,0,5},{147,0,44},{6,0,506},{134,11,506},{135,11, +1553},{4,0,309},{5,0,462},{7,0,970},{7,0,1097},{7,11,1385},{11,11,582},{11,11, +650},{11,11,901},{11,11,949},{12,11,232},{12,11,236},{13,11,413},{13,11,501},{18 +,11,116},{22,0,30},{150,0,33},{5,10,222},{9,0,140},{138,10,534},{6,0,1056},{137, +10,906},{134,0,1704},{138,10,503},{134,0,1036},{5,10,154},{7,10,1491},{10,10,379 +},{138,10,485},{4,11,383},{133,10,716},{134,0,1315},{5,0,86},{7,0,743},{9,0,85}, +{10,0,281},{10,0,432},{11,0,825},{12,0,251},{13,0,118},{142,0,378},{4,10,91},{5, +10,388},{5,10,845},{6,10,206},{6,10,252},{6,10,365},{7,10,136},{7,10,531},{8,0, +264},{136,10,621},{5,0,524},{133,0,744},{5,11,277},{141,11,247},{132,11,435},{10 +,0,107},{140,0,436},{132,0,927},{10,0,123},{12,0,670},{146,0,94},{7,0,1149},{9,0 +,156},{138,0,957},{5,11,265},{6,11,212},{135,11,28},{133,0,778},{133,0,502},{8,0 +,196},{10,0,283},{139,0,406},{135,10,576},{136,11,535},{134,0,1312},{5,10,771},{ +5,10,863},{5,10,898},{6,10,1632},{6,10,1644},{134,10,1780},{5,0,855},{5,10,331}, +{135,11,1487},{132,11,702},{5,11,808},{135,11,2045},{7,0,1400},{9,0,446},{138,0, +45},{140,10,632},{132,0,1003},{5,11,166},{8,11,739},{140,11,511},{5,10,107},{7, +10,201},{136,10,518},{6,10,446},{135,10,1817},{134,0,1532},{134,0,1097},{4,11, +119},{5,11,170},{5,11,447},{7,11,1708},{7,11,1889},{9,11,357},{9,11,719},{12,11, +486},{140,11,596},{9,10,851},{141,10,510},{4,10,504},{7,0,612},{8,0,545},{8,0, +568},{8,0,642},{9,0,717},{10,0,541},{10,0,763},{11,0,449},{12,0,489},{13,0,153}, +{13,0,296},{14,0,138},{14,0,392},{15,0,50},{16,0,6},{16,0,12},{148,0,9},{4,11, +450},{135,11,1158},{5,10,883},{5,10,975},{8,10,392},{11,0,54},{13,0,173},{13,0, +294},{148,10,7},{13,0,455},{15,0,99},{15,0,129},{144,0,68},{135,0,172},{132,11, +754},{5,10,922},{134,10,1707},{134,0,1029},{17,11,39},{148,11,36},{4,0,568},{5, +10,993},{7,10,515},{137,10,91},{132,0,732},{10,0,617},{138,11,617},{134,0,974},{ +7,0,989},{10,0,377},{12,0,363},{13,0,68},{13,0,94},{14,0,108},{142,0,306},{136,0 +,733},{132,0,428},{7,0,1789},{135,11,1062},{7,0,2015},{140,0,665},{135,10,1433}, +{5,0,287},{7,10,921},{8,10,580},{8,10,593},{8,10,630},{138,10,28},{138,0,806},{4 +,10,911},{5,10,867},{5,10,1013},{7,10,2034},{8,10,798},{136,10,813},{134,0,1539} +,{8,11,523},{150,11,34},{135,11,740},{7,11,238},{7,11,2033},{8,11,120},{8,11,188 +},{8,11,659},{9,11,598},{10,11,466},{12,11,342},{12,11,588},{13,11,503},{14,11, +246},{143,11,92},{7,0,1563},{141,0,182},{5,10,135},{6,10,519},{7,10,1722},{10,10 +,271},{11,10,261},{145,10,54},{14,10,338},{148,10,81},{4,10,300},{5,10,436},{135 +,0,484},{145,11,114},{6,0,1623},{134,0,1681},{133,11,640},{4,11,201},{7,11,1744} +,{8,11,602},{11,11,247},{11,11,826},{145,11,65},{8,11,164},{146,11,62},{6,0,1833 +},{6,0,1861},{136,0,878},{134,0,1569},{8,10,357},{10,10,745},{14,10,426},{17,10, +94},{147,10,57},{12,0,93},{12,0,501},{13,0,362},{14,0,151},{15,0,40},{15,0,59},{ +16,0,46},{17,0,25},{18,0,14},{18,0,134},{19,0,25},{19,0,69},{20,0,16},{20,0,19}, +{20,0,66},{21,0,23},{21,0,25},{150,0,42},{6,0,1748},{8,0,715},{9,0,802},{10,0,46 +},{10,0,819},{13,0,308},{14,0,351},{14,0,363},{146,0,67},{132,0,994},{4,0,63},{ +133,0,347},{132,0,591},{133,0,749},{7,11,1577},{10,11,304},{10,11,549},{11,11, +424},{12,11,365},{13,11,220},{13,11,240},{142,11,33},{133,0,366},{5,10,387},{7,0 +,557},{12,0,547},{142,0,86},{135,0,1747},{132,11,907},{5,11,100},{10,11,329},{12 +,11,416},{149,11,29},{4,10,6},{5,10,708},{136,10,75},{7,10,1351},{9,10,581},{10, +10,639},{11,10,453},{140,10,584},{4,10,303},{135,0,89},{138,10,772},{132,11,176} +,{5,11,636},{5,11,998},{8,11,26},{137,11,358},{7,11,9},{7,11,1508},{9,11,317},{ +10,11,210},{10,11,292},{10,11,533},{11,11,555},{12,11,526},{12,11,607},{13,11, +263},{13,11,459},{142,11,271},{134,0,1463},{6,0,772},{6,0,1137},{139,11,595},{7, +0,977},{139,11,66},{138,0,893},{20,0,48},{148,11,48},{5,0,824},{133,0,941},{134, +11,295},{4,10,106},{7,0,1543},{7,0,1785},{10,0,690},{139,10,717},{7,0,440},{8,0, +230},{139,0,106},{5,10,890},{133,10,988},{6,10,626},{142,10,431},{10,11,127},{ +141,11,27},{10,10,706},{17,0,32},{150,10,44},{132,0,216},{137,0,332},{4,10,698}, +{136,11,119},{139,11,267},{138,10,17},{11,11,526},{11,11,939},{141,11,290},{7,11 +,1167},{11,11,934},{13,11,391},{145,11,76},{139,11,39},{134,10,84},{4,0,914},{5, +0,800},{133,0,852},{10,0,416},{141,0,115},{7,0,564},{142,0,168},{4,0,918},{133,0 +,876},{134,0,1764},{152,0,3},{4,0,92},{5,0,274},{7,11,126},{136,11,84},{140,10, +498},{136,11,790},{5,10,986},{6,10,130},{7,10,1582},{8,0,501},{8,10,458},{10,10, +101},{10,10,318},{138,10,823},{6,11,64},{12,11,377},{141,11,309},{5,0,743},{138, +0,851},{4,0,49},{7,0,280},{135,0,1633},{134,0,879},{136,0,47},{7,10,1644},{137, +10,129},{132,0,865},{134,0,1202},{9,11,34},{139,11,484},{135,10,997},{5,0,272},{ +5,0,908},{5,0,942},{8,0,197},{9,0,47},{11,0,538},{139,0,742},{6,11,1700},{7,11, +26},{7,11,293},{7,11,382},{7,11,1026},{7,11,1087},{7,11,2027},{8,11,24},{8,11, +114},{8,11,252},{8,11,727},{8,11,729},{9,11,30},{9,11,199},{9,11,231},{9,11,251} +,{9,11,334},{9,11,361},{9,11,488},{9,11,712},{10,11,55},{10,11,60},{10,11,232},{ +10,11,332},{10,11,384},{10,11,396},{10,11,504},{10,11,542},{10,11,652},{11,11,20 +},{11,11,48},{11,11,207},{11,11,291},{11,11,298},{11,11,342},{11,11,365},{11,11, +394},{11,11,620},{11,11,705},{11,11,1017},{12,11,123},{12,11,340},{12,11,406},{ +12,11,643},{13,11,61},{13,11,269},{13,11,311},{13,11,319},{13,11,486},{14,11,234 +},{15,11,62},{15,11,85},{16,11,71},{18,11,119},{148,11,105},{6,0,1455},{150,11, +37},{135,10,1927},{135,0,1911},{137,0,891},{7,10,1756},{137,10,98},{7,10,1046},{ +139,10,160},{132,0,761},{6,11,379},{7,11,270},{7,11,1116},{8,11,176},{8,11,183}, +{9,11,432},{9,11,661},{12,11,247},{12,11,617},{146,11,125},{6,10,45},{7,10,433}, +{8,10,129},{9,10,21},{10,10,392},{11,10,79},{12,10,499},{13,10,199},{141,10,451} +,{4,0,407},{5,11,792},{133,11,900},{132,0,560},{135,0,183},{7,10,558},{8,10,353} +,{141,0,490},{4,0,475},{5,10,785},{6,0,731},{11,0,35},{13,0,71},{13,0,177},{142, +0,422},{8,10,81},{9,10,189},{9,10,201},{11,10,478},{11,10,712},{141,10,338},{4,0 +,418},{4,0,819},{133,10,353},{151,10,26},{4,11,901},{133,11,776},{132,0,575},{7, +0,818},{16,0,92},{17,0,14},{17,0,45},{18,0,75},{148,0,18},{6,0,222},{7,0,636},{7 +,0,1620},{8,0,409},{9,0,693},{139,0,77},{6,10,25},{7,10,855},{7,10,1258},{144,10 +,32},{6,0,1880},{6,0,1887},{6,0,1918},{6,0,1924},{9,0,967},{9,0,995},{9,0,1015}, +{12,0,826},{12,0,849},{12,0,857},{12,0,860},{12,0,886},{12,0,932},{18,0,228},{18 +,0,231},{146,0,240},{134,0,633},{134,0,1308},{4,11,37},{5,11,334},{135,11,1253}, +{4,10,4},{7,10,1118},{7,10,1320},{7,10,1706},{8,10,277},{9,10,622},{10,0,86},{11 +,10,724},{12,10,350},{12,10,397},{13,10,28},{13,10,159},{15,10,89},{18,10,5},{19 +,10,9},{20,10,34},{150,10,47},{132,11,508},{137,11,448},{12,11,107},{146,11,31}, +{132,0,817},{134,0,663},{133,0,882},{134,0,914},{132,11,540},{132,11,533},{136, +11,608},{8,0,885},{138,0,865},{132,0,426},{6,0,58},{7,0,745},{7,0,1969},{8,0,399 +},{8,0,675},{9,0,479},{9,0,731},{10,0,330},{10,0,593},{10,0,817},{11,0,32},{11,0 +,133},{11,0,221},{145,0,68},{134,10,255},{7,0,102},{137,0,538},{137,10,216},{7, +11,253},{136,11,549},{135,11,912},{9,10,183},{139,10,286},{11,10,956},{151,10,3} +,{8,11,527},{18,11,60},{147,11,24},{4,10,536},{7,10,1141},{10,10,723},{139,10, +371},{133,11,920},{7,0,876},{135,10,285},{135,10,560},{132,10,690},{142,11,126}, +{11,10,33},{12,10,571},{149,10,1},{133,0,566},{4,11,483},{9,0,139},{10,0,399},{ +11,0,469},{12,0,634},{141,0,223},{6,0,48},{135,0,63},{7,10,1862},{12,10,491},{12 +,10,520},{13,10,383},{14,10,244},{146,0,12},{135,11,1665},{132,11,448},{9,11,495 +},{146,11,104},{6,0,114},{7,0,1224},{7,0,1556},{136,0,3},{4,10,190},{133,10,554} +,{5,10,1001},{8,0,576},{137,0,267},{133,10,446},{133,0,933},{139,11,1009},{8,11, +653},{13,11,93},{147,11,14},{6,0,692},{6,0,821},{134,0,1077},{5,11,172},{135,11, +801},{138,0,752},{4,0,375},{134,0,638},{134,0,1011},{140,11,540},{5,11,260},{137 +,0,96},{139,11,587},{135,10,1231},{4,10,304},{12,0,30},{13,0,148},{14,0,87},{14, +0,182},{16,0,42},{148,0,70},{6,0,1398},{7,0,56},{7,0,1989},{8,0,337},{8,0,738},{ +9,0,600},{12,0,37},{13,0,447},{142,0,92},{138,0,666},{5,0,394},{7,0,487},{136,0, +246},{6,10,53},{6,10,199},{7,10,1408},{8,10,32},{8,10,93},{9,0,437},{10,10,397}, +{10,10,629},{11,10,593},{11,10,763},{13,10,326},{145,10,35},{134,10,105},{9,0, +320},{10,0,506},{138,10,794},{7,11,57},{8,11,167},{8,11,375},{9,11,82},{9,11,561 +},{10,11,620},{10,11,770},{11,10,704},{141,10,396},{5,10,114},{5,10,255},{6,0, +1003},{141,10,285},{7,0,866},{135,0,1163},{133,11,531},{132,0,328},{7,10,2035},{ +8,10,19},{9,10,89},{138,10,831},{8,11,194},{136,11,756},{136,0,1000},{5,11,453}, +{134,11,441},{4,0,101},{5,0,833},{7,0,1171},{136,0,744},{133,0,726},{136,10,746} +,{138,0,176},{6,0,9},{6,0,397},{7,0,53},{7,0,1742},{10,0,632},{11,0,828},{140,0, +146},{135,11,22},{145,11,64},{132,0,839},{11,0,417},{12,0,223},{140,0,265},{4,11 +,102},{7,11,815},{7,11,1699},{139,11,964},{5,10,955},{136,10,814},{6,0,1931},{6, +0,2007},{18,0,246},{146,0,247},{8,0,198},{11,0,29},{140,0,534},{135,0,1771},{6,0 +,846},{7,11,1010},{11,11,733},{11,11,759},{12,11,563},{13,11,34},{14,11,101},{18 +,11,45},{146,11,129},{4,0,186},{5,0,157},{8,0,168},{138,0,6},{132,11,899},{133, +10,56},{148,10,100},{133,0,875},{5,0,773},{5,0,991},{6,0,1635},{134,0,1788},{6,0 +,1274},{9,0,477},{141,0,78},{4,0,639},{6,11,52},{7,0,111},{8,0,581},{9,11,104},{ +9,11,559},{10,10,4},{10,10,13},{11,10,638},{12,0,177},{12,11,308},{19,11,87},{ +148,10,57},{132,11,604},{4,11,301},{133,10,738},{133,10,758},{134,0,1747},{7,11, +1440},{11,11,854},{11,11,872},{11,11,921},{12,11,551},{13,11,472},{142,11,367},{ +7,0,1364},{7,0,1907},{141,0,158},{134,0,873},{4,0,404},{4,0,659},{7,0,552},{135, +0,675},{135,10,1112},{139,10,328},{7,11,508},{137,10,133},{133,0,391},{5,10,110} +,{6,10,169},{6,10,1702},{7,10,400},{8,10,538},{9,10,184},{9,10,524},{140,10,218} +,{6,11,310},{7,11,1849},{8,11,72},{8,11,272},{8,11,431},{9,11,12},{9,11,351},{10 +,11,563},{10,11,630},{10,11,810},{11,11,367},{11,11,599},{11,11,686},{140,11,672 +},{5,0,540},{6,0,1697},{136,0,668},{132,0,883},{134,0,78},{6,10,133},{9,10,353}, +{11,10,993},{12,0,628},{146,0,79},{6,11,181},{7,11,537},{8,11,64},{9,11,127},{10 +,11,496},{12,11,510},{141,11,384},{6,10,93},{7,10,1422},{7,10,1851},{8,10,673},{ +9,10,529},{140,10,43},{137,10,371},{134,0,1460},{134,0,962},{4,11,244},{135,11, +233},{9,10,25},{10,10,467},{138,10,559},{4,10,335},{135,10,942},{133,0,460},{135 +,11,334},{134,11,1650},{4,0,199},{139,0,34},{5,10,601},{8,10,39},{10,10,773},{11 +,10,84},{12,10,205},{142,10,1},{133,10,870},{134,0,388},{14,0,474},{148,0,120},{ +133,11,369},{139,0,271},{4,0,511},{4,10,181},{9,0,333},{9,0,379},{10,0,602},{11, +0,441},{11,0,723},{11,0,976},{140,0,357},{134,0,608},{134,10,1652},{9,11,338},{ +150,0,49},{140,0,988},{134,0,617},{5,0,938},{136,0,707},{132,10,97},{5,10,147},{ +6,10,286},{7,10,1362},{141,10,176},{6,0,756},{134,0,1149},{133,11,896},{6,10,375 +},{7,10,169},{7,10,254},{136,10,780},{134,0,1583},{135,10,1447},{139,0,285},{7, +11,1117},{8,11,393},{136,11,539},{135,0,344},{6,0,469},{7,0,1709},{138,0,515},{5 +,10,629},{135,10,1549},{5,11,4},{5,11,810},{6,11,13},{6,11,538},{6,11,1690},{6, +11,1726},{7,11,499},{7,11,1819},{8,11,148},{8,11,696},{8,11,791},{12,11,125},{13 +,11,54},{143,11,9},{135,11,1268},{137,0,404},{132,0,500},{5,0,68},{134,0,383},{ +11,0,216},{139,0,340},{4,11,925},{5,11,803},{8,11,698},{138,11,828},{4,0,337},{6 +,0,353},{7,0,1934},{8,0,488},{137,0,429},{7,0,236},{7,0,1795},{8,0,259},{9,0,135 +},{9,0,177},{9,0,860},{10,0,825},{11,0,115},{11,0,370},{11,0,405},{11,0,604},{12 +,0,10},{12,0,667},{12,0,669},{13,0,76},{14,0,310},{15,0,76},{15,0,147},{148,0,23 +},{4,0,15},{4,0,490},{5,0,22},{6,0,244},{7,0,40},{7,0,200},{7,0,906},{7,0,1199}, +{9,0,616},{10,0,716},{11,0,635},{11,0,801},{140,0,458},{4,10,420},{140,0,756},{ +134,0,1504},{5,11,383},{134,0,757},{6,0,1266},{135,0,1735},{5,0,598},{7,0,791},{ +7,10,1570},{8,0,108},{9,0,123},{140,10,542},{142,11,410},{9,11,660},{138,11,347} +}; diff --git a/packages/runtime/vendor/brotli/c/enc/static_init.c b/packages/runtime/vendor/brotli/c/enc/static_init.c new file mode 100644 index 000000000..c0dff3a3a --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/static_init.c @@ -0,0 +1,59 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +#include "static_init.h" + +#include "../common/platform.h" +#include "../common/static_init.h" + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +#include "../common/dictionary.h" +#include "dictionary_hash.h" +#include "static_dict_lut.h" +#endif + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT != BROTLI_STATIC_INIT_NONE) +static BROTLI_BOOL DoBrotliEncoderStaticInit(void) { + const BrotliDictionary* dict = BrotliGetDictionary(); + BROTLI_BOOL ok = BrotliEncoderInitStaticDictionaryLut( + dict, kStaticDictionaryBuckets, kStaticDictionaryWords); + if (!ok) return BROTLI_FALSE; + ok = BrotliEncoderInitDictionaryHash(dict, kStaticDictionaryHashWords, + kStaticDictionaryHashLengths); + if (!ok) return BROTLI_FALSE; + return BROTLI_TRUE; +} +#endif /* BROTLI_STATIC_INIT_NONE */ + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) +static BROTLI_BOOL kEarlyInitOk; +static __attribute__((constructor)) void BrotliEncoderStaticInitEarly(void) { + kEarlyInitOk = DoBrotliEncoderStaticInit(); +} +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_LAZY) +static BROTLI_BOOL kLazyInitOk; +void BrotliEncoderLazyStaticInitInner(void) { + kLazyInitOk = DoBrotliEncoderStaticInit(); +} +#endif /* BROTLI_STATIC_INIT_EARLY */ + +BROTLI_BOOL BrotliEncoderEnsureStaticInit(void) { +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_NONE) + return BROTLI_TRUE; +#elif (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_EARLY) + return kEarlyInitOk; +#else + return kLazyInitOk; +#endif +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/static_init.h b/packages/runtime/vendor/brotli/c/enc/static_init.h new file mode 100644 index 000000000..e5cb23916 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/static_init.h @@ -0,0 +1,30 @@ +/* Copyright 2025 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Central point for static initialization. */ + +#ifndef THIRD_PARTY_BROTLI_ENC_STATIC_INIT_H_ +#define THIRD_PARTY_BROTLI_ENC_STATIC_INIT_H_ + +#include "../common/platform.h" +#include "../common/static_init.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#if (BROTLI_STATIC_INIT == BROTLI_STATIC_INIT_LAZY) +BROTLI_INTERNAL void BrotliEncoderLazyStaticInitInner(void); +BROTLI_INTERNAL void BrotliEncoderLazyStaticInit(void); +#endif /* BROTLI_STATIC_INIT */ + +BROTLI_INTERNAL BROTLI_BOOL BrotliEncoderEnsureStaticInit(void); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif // THIRD_PARTY_BROTLI_ENC_STATIC_INIT_H_ diff --git a/packages/runtime/vendor/brotli/c/enc/utf8_util.c b/packages/runtime/vendor/brotli/c/enc/utf8_util.c new file mode 100644 index 000000000..d46c3644e --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/utf8_util.c @@ -0,0 +1,85 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Heuristics for deciding about the UTF8-ness of strings. */ + +#include "utf8_util.h" + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static size_t BrotliParseAsUTF8( + int* symbol, const uint8_t* input, size_t size) { + /* ASCII */ + if ((input[0] & 0x80) == 0) { + *symbol = input[0]; + if (*symbol > 0) { + return 1; + } + } + /* 2-byte UTF8 */ + if (size > 1u && + (input[0] & 0xE0) == 0xC0 && + (input[1] & 0xC0) == 0x80) { + *symbol = (((input[0] & 0x1F) << 6) | + (input[1] & 0x3F)); + if (*symbol > 0x7F) { + return 2; + } + } + /* 3-byte UFT8 */ + if (size > 2u && + (input[0] & 0xF0) == 0xE0 && + (input[1] & 0xC0) == 0x80 && + (input[2] & 0xC0) == 0x80) { + *symbol = (((input[0] & 0x0F) << 12) | + ((input[1] & 0x3F) << 6) | + (input[2] & 0x3F)); + if (*symbol > 0x7FF) { + return 3; + } + } + /* 4-byte UFT8 */ + if (size > 3u && + (input[0] & 0xF8) == 0xF0 && + (input[1] & 0xC0) == 0x80 && + (input[2] & 0xC0) == 0x80 && + (input[3] & 0xC0) == 0x80) { + *symbol = (((input[0] & 0x07) << 18) | + ((input[1] & 0x3F) << 12) | + ((input[2] & 0x3F) << 6) | + (input[3] & 0x3F)); + if (*symbol > 0xFFFF && *symbol <= 0x10FFFF) { + return 4; + } + } + /* Not UTF8, emit a special symbol above the UTF8-code space */ + *symbol = 0x110000 | input[0]; + return 1; +} + +/* Returns 1 if at least min_fraction of the data is UTF8-encoded.*/ +BROTLI_BOOL BrotliIsMostlyUTF8( + const uint8_t* data, const size_t pos, const size_t mask, + const size_t length, const double min_fraction) { + size_t size_utf8 = 0; + size_t i = 0; + while (i < length) { + int symbol; + size_t bytes_read = + BrotliParseAsUTF8(&symbol, &data[(pos + i) & mask], length - i); + i += bytes_read; + if (symbol < 0x110000) size_utf8 += bytes_read; + } + return TO_BROTLI_BOOL((double)size_utf8 > min_fraction * (double)length); +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif diff --git a/packages/runtime/vendor/brotli/c/enc/utf8_util.h b/packages/runtime/vendor/brotli/c/enc/utf8_util.h new file mode 100644 index 000000000..cae3dba7a --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/utf8_util.h @@ -0,0 +1,31 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Heuristics for deciding about the UTF8-ness of strings. */ + +#ifndef BROTLI_ENC_UTF8_UTIL_H_ +#define BROTLI_ENC_UTF8_UTIL_H_ + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +static const double kMinUTF8Ratio = 0.75; + +/* Returns 1 if at least min_fraction of the bytes between pos and + pos + length in the (data, mask) ring-buffer is UTF8-encoded, otherwise + returns 0. */ +BROTLI_INTERNAL BROTLI_BOOL BrotliIsMostlyUTF8( + const uint8_t* data, const size_t pos, const size_t mask, + const size_t length, const double min_fraction); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_UTF8_UTIL_H_ */ diff --git a/packages/runtime/vendor/brotli/c/enc/write_bits.h b/packages/runtime/vendor/brotli/c/enc/write_bits.h new file mode 100644 index 000000000..0cdc3372b --- /dev/null +++ b/packages/runtime/vendor/brotli/c/enc/write_bits.h @@ -0,0 +1,86 @@ +/* Copyright 2010 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Write bits into a byte array. */ + +#ifndef BROTLI_ENC_WRITE_BITS_H_ +#define BROTLI_ENC_WRITE_BITS_H_ + +#include "../common/platform.h" + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* This function writes bits into bytes in increasing addresses, and within + a byte least-significant-bit first. + + The function can write up to 56 bits in one go with WriteBits + Example: let's assume that 3 bits (Rs below) have been written already: + + BYTE-0 BYTE+1 BYTE+2 + + 0000 0RRR 0000 0000 0000 0000 + + Now, we could write 5 or less bits in MSB by just shifting by 3 + and OR'ing to BYTE-0. + + For n bits, we take the last 5 bits, OR that with high bits in BYTE-0, + and locate the rest in BYTE+1, BYTE+2, etc. */ +static BROTLI_INLINE void BrotliWriteBits(size_t n_bits, + uint64_t bits, + size_t* BROTLI_RESTRICT pos, + uint8_t* BROTLI_RESTRICT array) { + BROTLI_LOG(("WriteBits %2d 0x%08x%08x %10d\n", (int)n_bits, + (uint32_t)(bits >> 32), (uint32_t)(bits & 0xFFFFFFFF), + (int)*pos)); + BROTLI_DCHECK((bits >> n_bits) == 0); + BROTLI_DCHECK(n_bits <= 56); +#if defined(BROTLI_LITTLE_ENDIAN) + /* This branch of the code can write up to 56 bits at a time, + 7 bits are lost by being perhaps already in *p and at least + 1 bit is needed to initialize the bit-stream ahead (i.e. if 7 + bits are in *p and we write 57 bits, then the next write will + access a byte that was never initialized). */ + { + uint8_t* p = &array[*pos >> 3]; + uint64_t v = (uint64_t)(*p); /* Zero-extend 8 to 64 bits. */ + v |= bits << (*pos & 7); + BROTLI_UNALIGNED_STORE64LE(p, v); /* Set some bits. */ + *pos += n_bits; + } +#else + /* implicit & 0xFF is assumed for uint8_t arithmetics */ + { + uint8_t* array_pos = &array[*pos >> 3]; + const size_t bits_reserved_in_first_byte = (*pos & 7); + size_t bits_left_to_write; + bits <<= bits_reserved_in_first_byte; + *array_pos++ |= (uint8_t)bits; + for (bits_left_to_write = n_bits + bits_reserved_in_first_byte; + bits_left_to_write >= 9; + bits_left_to_write -= 8) { + bits >>= 8; + *array_pos++ = (uint8_t)bits; + } + *array_pos = 0; + *pos += n_bits; + } +#endif +} + +static BROTLI_INLINE void BrotliWriteBitsPrepareStorage( + size_t pos, uint8_t* array) { + BROTLI_LOG(("WriteBitsPrepareStorage %10d\n", (int)pos)); + BROTLI_DCHECK((pos & 7) == 0); + array[pos >> 3] = 0; +} + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_WRITE_BITS_H_ */ diff --git a/packages/runtime/vendor/brotli/c/include/brotli/decode.h b/packages/runtime/vendor/brotli/c/include/brotli/decode.h new file mode 100644 index 000000000..8d436db73 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/include/brotli/decode.h @@ -0,0 +1,409 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/** + * @file + * API for Brotli decompression. + */ + +#ifndef BROTLI_DEC_DECODE_H_ +#define BROTLI_DEC_DECODE_H_ + +#include +#include +#include /* IWYU pragma: export */ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/** + * Opaque structure that holds decoder state. + * + * Allocated and initialized with ::BrotliDecoderCreateInstance. + * Cleaned up and deallocated with ::BrotliDecoderDestroyInstance. + */ +typedef struct BrotliDecoderStateStruct BrotliDecoderState; + +/** + * Result type for ::BrotliDecoderDecompress and + * ::BrotliDecoderDecompressStream functions. + */ +typedef enum { + /** Decoding error, e.g. corrupted input or memory allocation problem. */ + BROTLI_DECODER_RESULT_ERROR = 0, + /** Decoding successfully completed. */ + BROTLI_DECODER_RESULT_SUCCESS = 1, + /** Partially done; should be called again with more input. */ + BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT = 2, + /** Partially done; should be called again with more output. */ + BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT = 3 +} BrotliDecoderResult; + +/** + * Template that evaluates items of ::BrotliDecoderErrorCode. + * + * Example: @code {.cpp} + * // Log Brotli error code. + * switch (brotliDecoderErrorCode) { + * #define CASE_(PREFIX, NAME, CODE) \ + * case BROTLI_DECODER ## PREFIX ## NAME: \ + * LOG(INFO) << "error code:" << #NAME; \ + * break; + * #define NEWLINE_ + * BROTLI_DECODER_ERROR_CODES_LIST(CASE_, NEWLINE_) + * #undef CASE_ + * #undef NEWLINE_ + * default: LOG(FATAL) << "unknown brotli error code"; + * } + * @endcode + */ +#define BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE, SEPARATOR) \ + BROTLI_ERROR_CODE(_, NO_ERROR, 0) SEPARATOR \ + /* Same as BrotliDecoderResult values */ \ + BROTLI_ERROR_CODE(_, SUCCESS, 1) SEPARATOR \ + BROTLI_ERROR_CODE(_, NEEDS_MORE_INPUT, 2) SEPARATOR \ + BROTLI_ERROR_CODE(_, NEEDS_MORE_OUTPUT, 3) SEPARATOR \ + \ + /* Errors caused by invalid input */ \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_NIBBLE, -1) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, RESERVED, -2) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_META_NIBBLE, -3) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_ALPHABET, -4) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_SAME, -5) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, CL_SPACE, -6) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, HUFFMAN_SPACE, -7) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, CONTEXT_MAP_REPEAT, -8) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_1, -9) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_2, -10) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, TRANSFORM, -11) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, DICTIONARY, -12) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, WINDOW_BITS, -13) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_FORMAT_, DISTANCE, -16) SEPARATOR \ + \ + /* -17 code is reserved */ \ + \ + BROTLI_ERROR_CODE(_ERROR_, COMPOUND_DICTIONARY, -18) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_, DICTIONARY_NOT_SET, -19) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_, INVALID_ARGUMENTS, -20) SEPARATOR \ + \ + /* Memory allocation problems */ \ + BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MODES, -21) SEPARATOR \ + /* Literal, insert and distance trees together */ \ + BROTLI_ERROR_CODE(_ERROR_ALLOC_, TREE_GROUPS, -22) SEPARATOR \ + /* -23..-24 codes are reserved for distinct tree groups */ \ + BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MAP, -25) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_1, -26) SEPARATOR \ + BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_2, -27) SEPARATOR \ + /* -28..-29 codes are reserved for dynamic ring-buffer allocation */ \ + BROTLI_ERROR_CODE(_ERROR_ALLOC_, BLOCK_TYPE_TREES, -30) SEPARATOR \ + \ + /* "Impossible" states */ \ + BROTLI_ERROR_CODE(_ERROR_, UNREACHABLE, -31) + +/** + * Error code for detailed logging / production debugging. + * + * See ::BrotliDecoderGetErrorCode and ::BROTLI_LAST_ERROR_CODE. + */ +typedef enum { +#define BROTLI_COMMA_ , +#define BROTLI_ERROR_CODE_ENUM_ITEM_(PREFIX, NAME, CODE) \ + BROTLI_DECODER ## PREFIX ## NAME = CODE + BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_ENUM_ITEM_, BROTLI_COMMA_) +} BrotliDecoderErrorCode; +#undef BROTLI_ERROR_CODE_ENUM_ITEM_ +#undef BROTLI_COMMA_ + +/** + * The value of the last error code, negative integer. + * + * All other error code values are in the range from ::BROTLI_LAST_ERROR_CODE + * to @c -1. There are also 4 other possible non-error codes @c 0 .. @c 3 in + * ::BrotliDecoderErrorCode enumeration. + */ +#define BROTLI_LAST_ERROR_CODE BROTLI_DECODER_ERROR_UNREACHABLE + +/** Options to be used with ::BrotliDecoderSetParameter. */ +typedef enum BrotliDecoderParameter { + /** + * Disable "canny" ring buffer allocation strategy. + * + * Ring buffer is allocated according to window size, despite the real size of + * the content. + */ + BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION = 0, + /** + * Flag that determines if "Large Window Brotli" is used. + */ + BROTLI_DECODER_PARAM_LARGE_WINDOW = 1 +} BrotliDecoderParameter; + +/** + * Sets the specified parameter to the given decoder instance. + * + * @param state decoder instance + * @param param parameter to set + * @param value new parameter value + * @returns ::BROTLI_FALSE if parameter is unrecognized, or value is invalid + * @returns ::BROTLI_TRUE if value is accepted + */ +BROTLI_DEC_API BROTLI_BOOL BrotliDecoderSetParameter( + BrotliDecoderState* state, BrotliDecoderParameter param, uint32_t value); + +/** + * Adds LZ77 prefix dictionary, adds or replaces built-in static dictionary and + * transforms. + * + * Attached dictionary ownership is not transferred. + * Data provided to this method should be kept accessible until + * decoding is finished and decoder instance is destroyed. + * + * @note Dictionaries can NOT be attached after actual decoding is started. + * + * @param state decoder instance + * @param type dictionary data format + * @param data_size length of memory region pointed by @p data + * @param data dictionary data in format corresponding to @p type + * @returns ::BROTLI_FALSE if dictionary is corrupted, + * or dictionary count limit is reached + * @returns ::BROTLI_TRUE if dictionary is accepted / attached + */ +BROTLI_DEC_API BROTLI_BOOL BrotliDecoderAttachDictionary( + BrotliDecoderState* state, BrotliSharedDictionaryType type, + size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]); + +/** + * Creates an instance of ::BrotliDecoderState and initializes it. + * + * The instance can be used once for decoding and should then be destroyed with + * ::BrotliDecoderDestroyInstance, it cannot be reused for a new decoding + * session. + * + * @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the + * case they are both zero, default memory allocators are used. @p opaque is + * passed to @p alloc_func and @p free_func when they are called. @p free_func + * has to return without doing anything when asked to free a NULL pointer. + * + * @param alloc_func custom memory allocation function + * @param free_func custom memory free function + * @param opaque custom memory manager handle + * @returns @c 0 if instance can not be allocated or initialized + * @returns pointer to initialized ::BrotliDecoderState otherwise + */ +BROTLI_DEC_API BrotliDecoderState* BrotliDecoderCreateInstance( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); + +/** + * Deinitializes and frees ::BrotliDecoderState instance. + * + * @param state decoder instance to be cleaned up and deallocated + */ +BROTLI_DEC_API void BrotliDecoderDestroyInstance(BrotliDecoderState* state); + +/** + * Performs one-shot memory-to-memory decompression. + * + * Decompresses the data in @p encoded_buffer into @p decoded_buffer, and sets + * @p *decoded_size to the decompressed length. + * + * @param encoded_size size of @p encoded_buffer + * @param encoded_buffer compressed data buffer with at least @p encoded_size + * addressable bytes + * @param[in, out] decoded_size @b in: size of @p decoded_buffer; \n + * @b out: length of decompressed data written to + * @p decoded_buffer + * @param decoded_buffer decompressed data destination buffer + * @returns ::BROTLI_DECODER_RESULT_ERROR if input is corrupted, memory + * allocation failed, or @p decoded_buffer is not large enough; + * @returns ::BROTLI_DECODER_RESULT_SUCCESS otherwise + */ +BROTLI_DEC_API BrotliDecoderResult BrotliDecoderDecompress( + size_t encoded_size, + const uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(encoded_size)], + size_t* decoded_size, + uint8_t decoded_buffer[BROTLI_ARRAY_PARAM(*decoded_size)]); + +/** + * Decompresses the input stream to the output stream. + * + * The values @p *available_in and @p *available_out must specify the number of + * bytes addressable at @p *next_in and @p *next_out respectively. + * When @p *available_out is @c 0, @p next_out is allowed to be @c NULL. + * + * After each call, @p *available_in will be decremented by the amount of input + * bytes consumed, and the @p *next_in pointer will be incremented by that + * amount. Similarly, @p *available_out will be decremented by the amount of + * output bytes written, and the @p *next_out pointer will be incremented by + * that amount. + * + * @p total_out, if it is not a null-pointer, will be set to the number + * of bytes decompressed since the last @p state initialization. + * + * @note Input is never overconsumed, so @p next_in and @p available_in could be + * passed to the next consumer after decoding is complete. + * + * @param state decoder instance + * @param[in, out] available_in @b in: amount of available input; \n + * @b out: amount of unused input + * @param[in, out] next_in pointer to the next compressed byte + * @param[in, out] available_out @b in: length of output buffer; \n + * @b out: remaining size of output buffer + * @param[in, out] next_out output buffer cursor; + * can be @c NULL if @p available_out is @c 0 + * @param[out] total_out number of bytes decompressed so far; can be @c NULL + * @returns ::BROTLI_DECODER_RESULT_ERROR if input is corrupted, memory + * allocation failed, arguments were invalid, etc.; + * use ::BrotliDecoderGetErrorCode to get detailed error code + * @returns ::BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT decoding is blocked until + * more input data is provided + * @returns ::BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT decoding is blocked until + * more output space is provided + * @returns ::BROTLI_DECODER_RESULT_SUCCESS decoding is finished, no more + * input might be consumed and no more output will be produced + */ +BROTLI_DEC_API BrotliDecoderResult BrotliDecoderDecompressStream( + BrotliDecoderState* state, size_t* available_in, const uint8_t** next_in, + size_t* available_out, uint8_t** next_out, size_t* total_out); + +/** + * Checks if decoder has more output. + * + * @param state decoder instance + * @returns ::BROTLI_TRUE, if decoder has some unconsumed output + * @returns ::BROTLI_FALSE otherwise + */ +BROTLI_DEC_API BROTLI_BOOL BrotliDecoderHasMoreOutput( + const BrotliDecoderState* state); + +/** + * Acquires pointer to internal output buffer. + * + * This method is used to make language bindings easier and more efficient: + * -# push data to ::BrotliDecoderDecompressStream, + * until ::BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT is reported + * -# use ::BrotliDecoderTakeOutput to peek bytes and copy to language-specific + * entity + * + * Also this could be useful if there is an output stream that is able to + * consume all the provided data (e.g. when data is saved to file system). + * + * @attention After every call to ::BrotliDecoderTakeOutput @p *size bytes of + * output are considered consumed for all consecutive calls to the + * instance methods; returned pointer becomes invalidated as well. + * + * @note Decoder output is not guaranteed to be contiguous. This means that + * after the size-unrestricted call to ::BrotliDecoderTakeOutput, + * immediate next call to ::BrotliDecoderTakeOutput may return more data. + * + * @param state decoder instance + * @param[in, out] size @b in: number of bytes caller is ready to take, @c 0 if + * any amount could be handled; \n + * @b out: amount of data pointed by returned pointer and + * considered consumed; \n + * out value is never greater than in value, unless it is @c 0 + * @returns pointer to output data + */ +BROTLI_DEC_API const uint8_t* BrotliDecoderTakeOutput( + BrotliDecoderState* state, size_t* size); + +/** + * Checks if instance has already consumed input. + * + * Instance that returns ::BROTLI_FALSE is considered "fresh" and could be + * reused. + * + * @param state decoder instance + * @returns ::BROTLI_TRUE if decoder has already used some input bytes + * @returns ::BROTLI_FALSE otherwise + */ +BROTLI_DEC_API BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* state); + +/** + * Checks if decoder instance reached the final state. + * + * @param state decoder instance + * @returns ::BROTLI_TRUE if decoder is in a state where it reached the end of + * the input and produced all of the output + * @returns ::BROTLI_FALSE otherwise + */ +BROTLI_DEC_API BROTLI_BOOL BrotliDecoderIsFinished( + const BrotliDecoderState* state); + +/** + * Acquires a detailed error code. + * + * Should be used only after ::BrotliDecoderDecompressStream returns + * ::BROTLI_DECODER_RESULT_ERROR. + * + * See also ::BrotliDecoderErrorString + * + * @param state decoder instance + * @returns last saved error code + */ +BROTLI_DEC_API BrotliDecoderErrorCode BrotliDecoderGetErrorCode( + const BrotliDecoderState* state); + +/** + * Converts error code to a c-string. + */ +BROTLI_DEC_API const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c); + +/** + * Gets a decoder library version. + * + * Look at BROTLI_MAKE_HEX_VERSION for more information. + */ +BROTLI_DEC_API uint32_t BrotliDecoderVersion(void); + +/** + * Callback to fire on metadata block start. + * + * After this callback is fired, if @p size is not @c 0, it is followed by + * ::brotli_decoder_metadata_chunk_func as more metadata block contents become + * accessible. + * + * @param opaque callback handle + * @param size size of metadata block + */ +typedef void (*brotli_decoder_metadata_start_func)(void* opaque, size_t size); + +/** + * Callback to fire on metadata block chunk becomes available. + * + * This function can be invoked multiple times per metadata block; block should + * be considered finished when sum of @p size matches the announced metadata + * block size. Chunks contents pointed by @p data are transient and shouln not + * be accessed after leaving the callback. + * + * @param opaque callback handle + * @param data pointer to metadata contents + * @param size size of metadata block chunk, at least @c 1 + */ +typedef void (*brotli_decoder_metadata_chunk_func)(void* opaque, + const uint8_t* data, + size_t size); + +/** + * Sets callback for receiving metadata blocks. + * + * @param state decoder instance + * @param start_func callback on metadata block start + * @param chunk_func callback on metadata block chunk + * @param opaque callback handle + */ +BROTLI_DEC_API void BrotliDecoderSetMetadataCallbacks( + BrotliDecoderState* state, + brotli_decoder_metadata_start_func start_func, + brotli_decoder_metadata_chunk_func chunk_func, void* opaque); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_DEC_DECODE_H_ */ diff --git a/packages/runtime/vendor/brotli/c/include/brotli/encode.h b/packages/runtime/vendor/brotli/c/include/brotli/encode.h new file mode 100644 index 000000000..ac26ea8e6 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/include/brotli/encode.h @@ -0,0 +1,505 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/** + * @file + * API for Brotli compression. + */ + +#ifndef BROTLI_ENC_ENCODE_H_ +#define BROTLI_ENC_ENCODE_H_ + +#include +#include +#include /* IWYU pragma: export */ + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/** Minimal value for ::BROTLI_PARAM_LGWIN parameter. */ +#define BROTLI_MIN_WINDOW_BITS 10 +/** + * Maximal value for ::BROTLI_PARAM_LGWIN parameter. + * + * @note equal to @c BROTLI_MAX_DISTANCE_BITS constant. + */ +#define BROTLI_MAX_WINDOW_BITS 24 +/** + * Maximal value for ::BROTLI_PARAM_LGWIN parameter + * in "Large Window Brotli" (32-bit). + */ +#define BROTLI_LARGE_MAX_WINDOW_BITS 30 +/** Minimal value for ::BROTLI_PARAM_LGBLOCK parameter. */ +#define BROTLI_MIN_INPUT_BLOCK_BITS 16 +/** Maximal value for ::BROTLI_PARAM_LGBLOCK parameter. */ +#define BROTLI_MAX_INPUT_BLOCK_BITS 24 +/** Minimal value for ::BROTLI_PARAM_QUALITY parameter. */ +#define BROTLI_MIN_QUALITY 0 +/** Maximal value for ::BROTLI_PARAM_QUALITY parameter. */ +#define BROTLI_MAX_QUALITY 11 + +/** Options for ::BROTLI_PARAM_MODE parameter. */ +typedef enum BrotliEncoderMode { + /** + * Default compression mode. + * + * In this mode compressor does not know anything in advance about the + * properties of the input. + */ + BROTLI_MODE_GENERIC = 0, + /** Compression mode for UTF-8 formatted text input. */ + BROTLI_MODE_TEXT = 1, + /** Compression mode used in WOFF 2.0. */ + BROTLI_MODE_FONT = 2 +} BrotliEncoderMode; + +/** Default value for ::BROTLI_PARAM_QUALITY parameter. */ +#define BROTLI_DEFAULT_QUALITY 11 +/** Default value for ::BROTLI_PARAM_LGWIN parameter. */ +#define BROTLI_DEFAULT_WINDOW 22 +/** Default value for ::BROTLI_PARAM_MODE parameter. */ +#define BROTLI_DEFAULT_MODE BROTLI_MODE_GENERIC + +/** Operations that can be performed by streaming encoder. */ +typedef enum BrotliEncoderOperation { + /** + * Process input. + * + * Encoder may postpone producing output, until it has processed enough input. + */ + BROTLI_OPERATION_PROCESS = 0, + /** + * Produce output for all processed input. + * + * Actual flush is performed when input stream is depleted and there is enough + * space in output stream. This means that client should repeat + * ::BROTLI_OPERATION_FLUSH operation until @p available_in becomes @c 0, and + * ::BrotliEncoderHasMoreOutput returns ::BROTLI_FALSE. If output is acquired + * via ::BrotliEncoderTakeOutput, then operation should be repeated after + * output buffer is drained. + * + * @warning Until flush is complete, client @b SHOULD @b NOT swap, + * reduce or extend input stream. + * + * When flush is complete, output data will be sufficient for decoder to + * reproduce all the given input. + */ + BROTLI_OPERATION_FLUSH = 1, + /** + * Finalize the stream. + * + * Actual finalization is performed when input stream is depleted and there is + * enough space in output stream. This means that client should repeat + * ::BROTLI_OPERATION_FINISH operation until @p available_in becomes @c 0, and + * ::BrotliEncoderHasMoreOutput returns ::BROTLI_FALSE. If output is acquired + * via ::BrotliEncoderTakeOutput, then operation should be repeated after + * output buffer is drained. + * + * @warning Until finalization is complete, client @b SHOULD @b NOT swap, + * reduce or extend input stream. + * + * Helper function ::BrotliEncoderIsFinished checks if stream is finalized and + * output fully dumped. + * + * Adding more input data to finalized stream is impossible. + */ + BROTLI_OPERATION_FINISH = 2, + /** + * Emit metadata block to stream. + * + * Metadata is opaque to Brotli: neither encoder, nor decoder processes this + * data or relies on it. It may be used to pass some extra information from + * encoder client to decoder client without interfering with main data stream. + * + * @note Encoder may emit empty metadata blocks internally, to pad encoded + * stream to byte boundary. + * + * @warning Until emitting metadata is complete client @b SHOULD @b NOT swap, + * reduce or extend input stream. + * + * @warning The whole content of input buffer is considered to be the content + * of metadata block. Do @b NOT @e append metadata to input stream, + * before it is depleted with other operations. + * + * Stream is soft-flushed before metadata block is emitted. Metadata block + * @b MUST be no longer than than 16MiB. + */ + BROTLI_OPERATION_EMIT_METADATA = 3 +} BrotliEncoderOperation; + +/** Options to be used with ::BrotliEncoderSetParameter. */ +typedef enum BrotliEncoderParameter { + /** + * Tune encoder for specific input. + * + * ::BrotliEncoderMode enumerates all available values. + */ + BROTLI_PARAM_MODE = 0, + /** + * The main compression speed-density lever. + * + * The higher the quality, the slower the compression. Range is + * from ::BROTLI_MIN_QUALITY to ::BROTLI_MAX_QUALITY. + */ + BROTLI_PARAM_QUALITY = 1, + /** + * Recommended sliding LZ77 window size. + * + * Encoder may reduce this value, e.g. if input is much smaller than + * window size. + * + * Window size is `(1 << value) - 16`. + * + * Range is from ::BROTLI_MIN_WINDOW_BITS to ::BROTLI_MAX_WINDOW_BITS. + */ + BROTLI_PARAM_LGWIN = 2, + /** + * Recommended input block size. + * + * Encoder may reduce this value, e.g. if input is much smaller than input + * block size. + * + * Range is from ::BROTLI_MIN_INPUT_BLOCK_BITS to + * ::BROTLI_MAX_INPUT_BLOCK_BITS. + * + * @note Bigger input block size allows better compression, but consumes more + * memory. \n The rough formula of memory used for temporary input + * storage is `3 << lgBlock`. + */ + BROTLI_PARAM_LGBLOCK = 3, + /** + * Flag that affects usage of "literal context modeling" format feature. + * + * This flag is a "decoding-speed vs compression ratio" trade-off. + */ + BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING = 4, + /** + * Estimated total input size for all ::BrotliEncoderCompressStream calls. + * + * The default value is 0, which means that the total input size is unknown. + */ + BROTLI_PARAM_SIZE_HINT = 5, + /** + * Flag that determines if "Large Window Brotli" is used. + */ + BROTLI_PARAM_LARGE_WINDOW = 6, + /** + * Recommended number of postfix bits (NPOSTFIX). + * + * Encoder may change this value. + * + * Range is from 0 to ::BROTLI_MAX_NPOSTFIX. + */ + BROTLI_PARAM_NPOSTFIX = 7, + /** + * Recommended number of direct distance codes (NDIRECT). + * + * Encoder may change this value. + * + * Range is from 0 to (15 << NPOSTFIX) in steps of (1 << NPOSTFIX). + */ + BROTLI_PARAM_NDIRECT = 8, + /** + * Number of bytes of input stream already processed by a different instance. + * + * @note It is important to configure all the encoder instances with same + * parameters (except this one) in order to allow all the encoded parts + * obey the same restrictions implied by header. + * + * If offset is not 0, then stream header is omitted. + * In any case output start is byte aligned, so for proper streams stitching + * "predecessor" stream must be flushed. + * + * Range is not artificially limited, but all the values greater or equal to + * maximal window size have the same effect. Values greater than 2**30 are not + * allowed. + */ + BROTLI_PARAM_STREAM_OFFSET = 9 +} BrotliEncoderParameter; + +/** + * Opaque structure that holds encoder state. + * + * Allocated and initialized with ::BrotliEncoderCreateInstance. + * Cleaned up and deallocated with ::BrotliEncoderDestroyInstance. + */ +typedef struct BrotliEncoderStateStruct BrotliEncoderState; + +/** + * Sets the specified parameter to the given encoder instance. + * + * @param state encoder instance + * @param param parameter to set + * @param value new parameter value + * @returns ::BROTLI_FALSE if parameter is unrecognized, or value is invalid + * @returns ::BROTLI_FALSE if value of parameter can not be changed at current + * encoder state (e.g. when encoding is started, window size might be + * already encoded and therefore it is impossible to change it) + * @returns ::BROTLI_TRUE if value is accepted + * @warning invalid values might be accepted in case they would not break + * encoding process. + */ +BROTLI_ENC_API BROTLI_BOOL BrotliEncoderSetParameter( + BrotliEncoderState* state, BrotliEncoderParameter param, uint32_t value); + +/** + * Creates an instance of ::BrotliEncoderState and initializes it. + * + * @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the + * case they are both zero, default memory allocators are used. @p opaque is + * passed to @p alloc_func and @p free_func when they are called. @p free_func + * has to return without doing anything when asked to free a NULL pointer. + * + * @param alloc_func custom memory allocation function + * @param free_func custom memory free function + * @param opaque custom memory manager handle + * @returns @c 0 if instance can not be allocated or initialized + * @returns pointer to initialized ::BrotliEncoderState otherwise + */ +BROTLI_ENC_API BrotliEncoderState* BrotliEncoderCreateInstance( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); + +/** + * Deinitializes and frees ::BrotliEncoderState instance. + * + * @param state decoder instance to be cleaned up and deallocated + */ +BROTLI_ENC_API void BrotliEncoderDestroyInstance(BrotliEncoderState* state); + +/* Opaque type for pointer to different possible internal structures containing + dictionary prepared for the encoder */ +typedef struct BrotliEncoderPreparedDictionaryStruct + BrotliEncoderPreparedDictionary; + +/** + * Prepares a shared dictionary from the given file format for the encoder. + * + * @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the + * case they are both zero, default memory allocators are used. @p opaque is + * passed to @p alloc_func and @p free_func when they are called. @p free_func + * has to return without doing anything when asked to free a NULL pointer. + * + * @warning Created instance is "lean"; it does not contain copy of @p data, + * rather it contains only pointer to it; therefore, + * @p data @b MUST outlive the created instance. + * + * @param type type of dictionary stored in data + * @param data_size size of @p data buffer + * @param data pointer to the dictionary data + * @param quality the maximum Brotli quality to prepare the dictionary for, + * use BROTLI_MAX_QUALITY by default + * @param alloc_func custom memory allocation function + * @param free_func custom memory free function + * @param opaque custom memory manager handle + */ +BROTLI_ENC_API BrotliEncoderPreparedDictionary* +BrotliEncoderPrepareDictionary(BrotliSharedDictionaryType type, + size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)], + int quality, + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); + +BROTLI_ENC_API void BrotliEncoderDestroyPreparedDictionary( + BrotliEncoderPreparedDictionary* dictionary); + +/** + * Attaches a prepared dictionary of any type to the encoder. Can be used + * multiple times to attach multiple dictionaries. The dictionary type was + * determined by BrotliEncoderPrepareDictionary. Multiple raw prefix + * dictionaries and/or max 1 serialized dictionary with custom words can be + * attached. + * + * @returns ::BROTLI_FALSE in case of error + * @returns ::BROTLI_TRUE otherwise + */ +BROTLI_ENC_API BROTLI_BOOL BrotliEncoderAttachPreparedDictionary( + BrotliEncoderState* state, + const BrotliEncoderPreparedDictionary* dictionary); + +/** + * Calculates the output size bound for the given @p input_size. + * + * @warning Result is only valid if quality is at least @c 2 and, in + * case ::BrotliEncoderCompressStream was used, no flushes + * (::BROTLI_OPERATION_FLUSH) were performed. + * + * @param input_size size of projected input + * @returns @c 0 if result does not fit @c size_t + */ +BROTLI_ENC_API size_t BrotliEncoderMaxCompressedSize(size_t input_size); + +/** + * Performs one-shot memory-to-memory compression. + * + * Compresses the data in @p input_buffer into @p encoded_buffer, and sets + * @p *encoded_size to the compressed length. + * + * @note If ::BrotliEncoderMaxCompressedSize(@p input_size) returns non-zero + * value, then output is guaranteed to be no longer than that. + * + * @note If @p lgwin is greater than ::BROTLI_MAX_WINDOW_BITS then resulting + * stream might be incompatible with RFC 7932; to decode such streams, + * decoder should be configured with + * ::BROTLI_DECODER_PARAM_LARGE_WINDOW = @c 1 + * + * @param quality quality parameter value, e.g. ::BROTLI_DEFAULT_QUALITY + * @param lgwin lgwin parameter value, e.g. ::BROTLI_DEFAULT_WINDOW + * @param mode mode parameter value, e.g. ::BROTLI_DEFAULT_MODE + * @param input_size size of @p input_buffer + * @param input_buffer input data buffer with at least @p input_size + * addressable bytes + * @param[in, out] encoded_size @b in: size of @p encoded_buffer; \n + * @b out: length of compressed data written to + * @p encoded_buffer, or @c 0 if compression fails + * @param encoded_buffer compressed data destination buffer + * @returns ::BROTLI_FALSE in case of compression error + * @returns ::BROTLI_FALSE if output buffer is too small + * @returns ::BROTLI_TRUE otherwise + */ +BROTLI_ENC_API BROTLI_BOOL BrotliEncoderCompress( + int quality, int lgwin, BrotliEncoderMode mode, size_t input_size, + const uint8_t input_buffer[BROTLI_ARRAY_PARAM(input_size)], + size_t* encoded_size, + uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(*encoded_size)]); + +/** + * Compresses input stream to output stream. + * + * The values @p *available_in and @p *available_out must specify the number of + * bytes addressable at @p *next_in and @p *next_out respectively. + * When @p *available_out is @c 0, @p next_out is allowed to be @c NULL. + * + * After each call, @p *available_in will be decremented by the amount of input + * bytes consumed, and the @p *next_in pointer will be incremented by that + * amount. Similarly, @p *available_out will be decremented by the amount of + * output bytes written, and the @p *next_out pointer will be incremented by + * that amount. + * + * @p total_out, if it is not a null-pointer, will be set to the number + * of bytes compressed since the last @p state initialization. + * + * + * + * Internally workflow consists of 3 tasks: + * -# (optionally) copy input data to internal buffer + * -# actually compress data and (optionally) store it to internal buffer + * -# (optionally) copy compressed bytes from internal buffer to output stream + * + * Whenever all 3 tasks can't move forward anymore, or error occurs, this + * method returns the control flow to caller. + * + * @p op is used to perform flush, finish the stream, or inject metadata block. + * See ::BrotliEncoderOperation for more information. + * + * Flushing the stream means forcing encoding of all input passed to encoder and + * completing the current output block, so it could be fully decoded by stream + * decoder. To perform flush set @p op to ::BROTLI_OPERATION_FLUSH. + * Under some circumstances (e.g. lack of output stream capacity) this operation + * would require several calls to ::BrotliEncoderCompressStream. The method must + * be called again until both input stream is depleted and encoder has no more + * output (see ::BrotliEncoderHasMoreOutput) after the method is called. + * + * Finishing the stream means encoding of all input passed to encoder and + * adding specific "final" marks, so stream decoder could determine that stream + * is complete. To perform finish set @p op to ::BROTLI_OPERATION_FINISH. + * Under some circumstances (e.g. lack of output stream capacity) this operation + * would require several calls to ::BrotliEncoderCompressStream. The method must + * be called again until both input stream is depleted and encoder has no more + * output (see ::BrotliEncoderHasMoreOutput) after the method is called. + * + * @warning When flushing and finishing, @p op should not change until operation + * is complete; input stream should not be swapped, reduced or + * extended as well. + * + * @param state encoder instance + * @param op requested operation + * @param[in, out] available_in @b in: amount of available input; \n + * @b out: amount of unused input + * @param[in, out] next_in pointer to the next input byte + * @param[in, out] available_out @b in: length of output buffer; \n + * @b out: remaining size of output buffer + * @param[in, out] next_out compressed output buffer cursor; + * can be @c NULL if @p available_out is @c 0 + * @param[out] total_out number of bytes produced so far; can be @c NULL + * @returns ::BROTLI_FALSE if there was an error + * @returns ::BROTLI_TRUE otherwise + */ +BROTLI_ENC_API BROTLI_BOOL BrotliEncoderCompressStream( + BrotliEncoderState* state, BrotliEncoderOperation op, size_t* available_in, + const uint8_t** next_in, size_t* available_out, uint8_t** next_out, + size_t* total_out); + +/** + * Checks if encoder instance reached the final state. + * + * @param state encoder instance + * @returns ::BROTLI_TRUE if encoder is in a state where it reached the end of + * the input and produced all of the output + * @returns ::BROTLI_FALSE otherwise + */ +BROTLI_ENC_API BROTLI_BOOL BrotliEncoderIsFinished(BrotliEncoderState* state); + +/** + * Checks if encoder has more output. + * + * @param state encoder instance + * @returns ::BROTLI_TRUE, if encoder has some unconsumed output + * @returns ::BROTLI_FALSE otherwise + */ +BROTLI_ENC_API BROTLI_BOOL BrotliEncoderHasMoreOutput( + BrotliEncoderState* state); + +/** + * Acquires pointer to internal output buffer. + * + * This method is used to make language bindings easier and more efficient: + * -# push data to ::BrotliEncoderCompressStream, + * until ::BrotliEncoderHasMoreOutput returns BROTLI_TRUE + * -# use ::BrotliEncoderTakeOutput to peek bytes and copy to language-specific + * entity + * + * Also this could be useful if there is an output stream that is able to + * consume all the provided data (e.g. when data is saved to file system). + * + * @attention After every call to ::BrotliEncoderTakeOutput @p *size bytes of + * output are considered consumed for all consecutive calls to the + * instance methods; returned pointer becomes invalidated as well. + * + * @note Encoder output is not guaranteed to be contiguous. This means that + * after the size-unrestricted call to ::BrotliEncoderTakeOutput, + * immediate next call to ::BrotliEncoderTakeOutput may return more data. + * + * @param state encoder instance + * @param[in, out] size @b in: number of bytes caller is ready to take, @c 0 if + * any amount could be handled; \n + * @b out: amount of data pointed by returned pointer and + * considered consumed; \n + * out value is never greater than in value, unless it is @c 0 + * @returns pointer to output data + */ +BROTLI_ENC_API const uint8_t* BrotliEncoderTakeOutput( + BrotliEncoderState* state, size_t* size); + +/* Returns the estimated peak memory usage (in bytes) of the BrotliCompress() + function, not counting the memory needed for the input and output. */ +BROTLI_ENC_EXTRA_API size_t BrotliEncoderEstimatePeakMemoryUsage( + int quality, int lgwin, size_t input_size); +/* Returns 0 if dictionary is not valid; otherwise returns allocation size. */ +BROTLI_ENC_EXTRA_API size_t BrotliEncoderGetPreparedDictionarySize( + const BrotliEncoderPreparedDictionary* dictionary); + +/** + * Gets an encoder library version. + * + * Look at BROTLI_MAKE_HEX_VERSION for more information. + */ +BROTLI_ENC_API uint32_t BrotliEncoderVersion(void); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_ENC_ENCODE_H_ */ diff --git a/packages/runtime/vendor/brotli/c/include/brotli/port.h b/packages/runtime/vendor/brotli/c/include/brotli/port.h new file mode 100644 index 000000000..11cefd791 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/include/brotli/port.h @@ -0,0 +1,302 @@ +/* Copyright 2016 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* Macros for compiler / platform specific API declarations. */ + +#ifndef BROTLI_COMMON_PORT_H_ +#define BROTLI_COMMON_PORT_H_ + +/* The following macros were borrowed from https://github.com/nemequ/hedley + * with permission of original author - Evan Nemerson */ + +/* >>> >>> >>> hedley macros */ + +#define BROTLI_MAKE_VERSION(major, minor, revision) \ + (((major) * 1000000) + ((minor) * 1000) + (revision)) + +#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) +#define BROTLI_GNUC_VERSION \ + BROTLI_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#elif defined(__GNUC__) +#define BROTLI_GNUC_VERSION BROTLI_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, 0) +#endif + +#if defined(BROTLI_GNUC_VERSION) +#define BROTLI_GNUC_VERSION_CHECK(major, minor, patch) \ + (BROTLI_GNUC_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_GNUC_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) +#define BROTLI_MSVC_VERSION \ + BROTLI_MAKE_VERSION((_MSC_FULL_VER / 10000000), \ + (_MSC_FULL_VER % 10000000) / 100000, \ + (_MSC_FULL_VER % 100000) / 100) +#elif defined(_MSC_FULL_VER) +#define BROTLI_MSVC_VERSION \ + BROTLI_MAKE_VERSION((_MSC_FULL_VER / 1000000), \ + (_MSC_FULL_VER % 1000000) / 10000, \ + (_MSC_FULL_VER % 10000) / 10) +#elif defined(_MSC_VER) +#define BROTLI_MSVC_VERSION \ + BROTLI_MAKE_VERSION(_MSC_VER / 100, _MSC_VER % 100, 0) +#endif + +#if !defined(_MSC_VER) +#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) (0) +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) +#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \ + (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) +#elif defined(_MSC_VER) && (_MSC_VER >= 1200) +#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \ + (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) +#else +#define BROTLI_MSVC_VERSION_CHECK(major, minor, patch) \ + (_MSC_VER >= ((major * 100) + (minor))) +#endif + +#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) +#define BROTLI_INTEL_VERSION \ + BROTLI_MAKE_VERSION(__INTEL_COMPILER / 100, \ + __INTEL_COMPILER % 100, \ + __INTEL_COMPILER_UPDATE) +#elif defined(__INTEL_COMPILER) +#define BROTLI_INTEL_VERSION \ + BROTLI_MAKE_VERSION(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) +#endif + +#if defined(BROTLI_INTEL_VERSION) +#define BROTLI_INTEL_VERSION_CHECK(major, minor, patch) \ + (BROTLI_INTEL_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_INTEL_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(__PGI) && \ + defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) +#define BROTLI_PGI_VERSION \ + BROTLI_MAKE_VERSION(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) +#endif + +#if defined(BROTLI_PGI_VERSION) +#define BROTLI_PGI_VERSION_CHECK(major, minor, patch) \ + (BROTLI_PGI_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_PGI_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) +#define BROTLI_SUNPRO_VERSION \ + BROTLI_MAKE_VERSION( \ + (((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), \ + (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), \ + (__SUNPRO_C & 0xf) * 10) +#elif defined(__SUNPRO_C) +#define BROTLI_SUNPRO_VERSION \ + BROTLI_MAKE_VERSION((__SUNPRO_C >> 8) & 0xf, \ + (__SUNPRO_C >> 4) & 0xf, \ + (__SUNPRO_C) & 0xf) +#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) +#define BROTLI_SUNPRO_VERSION \ + BROTLI_MAKE_VERSION( \ + (((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), \ + (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), \ + (__SUNPRO_CC & 0xf) * 10) +#elif defined(__SUNPRO_CC) +#define BROTLI_SUNPRO_VERSION \ + BROTLI_MAKE_VERSION((__SUNPRO_CC >> 8) & 0xf, \ + (__SUNPRO_CC >> 4) & 0xf, \ + (__SUNPRO_CC) & 0xf) +#endif + +#if defined(BROTLI_SUNPRO_VERSION) +#define BROTLI_SUNPRO_VERSION_CHECK(major, minor, patch) \ + (BROTLI_SUNPRO_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_SUNPRO_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) +#define BROTLI_ARM_VERSION \ + BROTLI_MAKE_VERSION((__ARMCOMPILER_VERSION / 1000000), \ + (__ARMCOMPILER_VERSION % 1000000) / 10000, \ + (__ARMCOMPILER_VERSION % 10000) / 100) +#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) +#define BROTLI_ARM_VERSION \ + BROTLI_MAKE_VERSION((__ARMCC_VERSION / 1000000), \ + (__ARMCC_VERSION % 1000000) / 10000, \ + (__ARMCC_VERSION % 10000) / 100) +#endif + +#if defined(BROTLI_ARM_VERSION) +#define BROTLI_ARM_VERSION_CHECK(major, minor, patch) \ + (BROTLI_ARM_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_ARM_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(__ibmxl__) +#define BROTLI_IBM_VERSION \ + BROTLI_MAKE_VERSION(__ibmxl_version__, \ + __ibmxl_release__, \ + __ibmxl_modification__) +#elif defined(__xlC__) && defined(__xlC_ver__) +#define BROTLI_IBM_VERSION \ + BROTLI_MAKE_VERSION(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) +#elif defined(__xlC__) +#define BROTLI_IBM_VERSION BROTLI_MAKE_VERSION(__xlC__ >> 8, __xlC__ & 0xff, 0) +#endif + +#if defined(BROTLI_IBM_VERSION) +#define BROTLI_IBM_VERSION_CHECK(major, minor, patch) \ + (BROTLI_IBM_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_IBM_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(__TI_COMPILER_VERSION__) +#define BROTLI_TI_VERSION \ + BROTLI_MAKE_VERSION((__TI_COMPILER_VERSION__ / 1000000), \ + (__TI_COMPILER_VERSION__ % 1000000) / 1000, \ + (__TI_COMPILER_VERSION__ % 1000)) +#endif + +#if defined(BROTLI_TI_VERSION) +#define BROTLI_TI_VERSION_CHECK(major, minor, patch) \ + (BROTLI_TI_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_TI_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(__IAR_SYSTEMS_ICC__) +#if __VER__ > 1000 +#define BROTLI_IAR_VERSION \ + BROTLI_MAKE_VERSION((__VER__ / 1000000), \ + (__VER__ / 1000) % 1000, \ + (__VER__ % 1000)) +#else +#define BROTLI_IAR_VERSION BROTLI_MAKE_VERSION(VER / 100, __VER__ % 100, 0) +#endif +#endif + +#if defined(BROTLI_IAR_VERSION) +#define BROTLI_IAR_VERSION_CHECK(major, minor, patch) \ + (BROTLI_IAR_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_IAR_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(__TINYC__) +#define BROTLI_TINYC_VERSION \ + BROTLI_MAKE_VERSION(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) +#endif + +#if defined(BROTLI_TINYC_VERSION) +#define BROTLI_TINYC_VERSION_CHECK(major, minor, patch) \ + (BROTLI_TINYC_VERSION >= BROTLI_MAKE_VERSION(major, minor, patch)) +#else +#define BROTLI_TINYC_VERSION_CHECK(major, minor, patch) (0) +#endif + +#if defined(__has_attribute) +#define BROTLI_GNUC_HAS_ATTRIBUTE(attribute, major, minor, patch) \ + __has_attribute(attribute) +#else +#define BROTLI_GNUC_HAS_ATTRIBUTE(attribute, major, minor, patch) \ + BROTLI_GNUC_VERSION_CHECK(major, minor, patch) +#endif + +#if defined(__has_builtin) +#define BROTLI_GNUC_HAS_BUILTIN(builtin, major, minor, patch) \ + __has_builtin(builtin) +#else +#define BROTLI_GNUC_HAS_BUILTIN(builtin, major, minor, patch) \ + BROTLI_GNUC_VERSION_CHECK(major, minor, patch) +#endif + +#if defined(__has_feature) +#define BROTLI_HAS_FEATURE(feature) __has_feature(feature) +#else +#define BROTLI_HAS_FEATURE(feature) (0) +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +#define BROTLI_PUBLIC +#elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \ + BROTLI_TI_VERSION_CHECK(8, 0, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \ + BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \ + BROTLI_IBM_VERSION_CHECK(13, 1, 0) || \ + BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \ + (BROTLI_TI_VERSION_CHECK(7, 3, 0) && \ + defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__)) +#define BROTLI_PUBLIC __attribute__ ((visibility ("default"))) +#else +#define BROTLI_PUBLIC +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +#define BROTLI_INTERNAL +#elif BROTLI_GNUC_VERSION_CHECK(3, 3, 0) || \ + BROTLI_TI_VERSION_CHECK(8, 0, 0) || \ + BROTLI_INTEL_VERSION_CHECK(16, 0, 0) || \ + BROTLI_ARM_VERSION_CHECK(4, 1, 0) || \ + BROTLI_IBM_VERSION_CHECK(13, 1, 0) || \ + BROTLI_SUNPRO_VERSION_CHECK(5, 11, 0) || \ + (BROTLI_TI_VERSION_CHECK(7, 3, 0) && \ + defined(__TI_GNU_ATTRIBUTE_SUPPORT__) && defined(__TI_EABI__)) +#define BROTLI_INTERNAL __attribute__ ((visibility ("hidden"))) +#else +#define BROTLI_INTERNAL +#endif + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + !defined(__STDC_NO_VLA__) && !defined(__cplusplus) && \ + !defined(__PGI) && !defined(__PGIC__) && !defined(__TINYC__) && \ + !defined(__clang__) +#define BROTLI_ARRAY_PARAM(name) (name) +#else +#define BROTLI_ARRAY_PARAM(name) +#endif + +/* <<< <<< <<< end of hedley macros. */ + +#if defined(BROTLI_SHARED_COMPILATION) +#if defined(_WIN32) +#if defined(BROTLICOMMON_SHARED_COMPILATION) +#define BROTLI_COMMON_API __declspec(dllexport) +#else /* !BROTLICOMMON_SHARED_COMPILATION */ +#define BROTLI_COMMON_API __declspec(dllimport) +#endif /* BROTLICOMMON_SHARED_COMPILATION */ +#if defined(BROTLIDEC_SHARED_COMPILATION) +#define BROTLI_DEC_API __declspec(dllexport) +#else /* !BROTLIDEC_SHARED_COMPILATION */ +#define BROTLI_DEC_API __declspec(dllimport) +#endif /* BROTLIDEC_SHARED_COMPILATION */ +#if defined(BROTLIENC_SHARED_COMPILATION) +#define BROTLI_ENC_API __declspec(dllexport) +#else /* !BROTLIENC_SHARED_COMPILATION */ +#define BROTLI_ENC_API __declspec(dllimport) +#endif /* BROTLIENC_SHARED_COMPILATION */ +#else /* !_WIN32 */ +#define BROTLI_COMMON_API BROTLI_PUBLIC +#define BROTLI_DEC_API BROTLI_PUBLIC +#define BROTLI_ENC_API BROTLI_PUBLIC +#endif /* _WIN32 */ +#else /* BROTLI_SHARED_COMPILATION */ +#define BROTLI_COMMON_API +#define BROTLI_DEC_API +#define BROTLI_ENC_API +#endif + +#if defined(BROTLI_BUILD_ENC_EXTRA_API) +#define BROTLI_ENC_EXTRA_API BROTLI_ENC_API +#else +#define BROTLI_ENC_EXTRA_API BROTLI_INTERNAL +#endif + +#endif /* BROTLI_COMMON_PORT_H_ */ diff --git a/packages/runtime/vendor/brotli/c/include/brotli/shared_dictionary.h b/packages/runtime/vendor/brotli/c/include/brotli/shared_dictionary.h new file mode 100644 index 000000000..2970c2dcc --- /dev/null +++ b/packages/runtime/vendor/brotli/c/include/brotli/shared_dictionary.h @@ -0,0 +1,100 @@ +/* Copyright 2017 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/* (Opaque) Shared Dictionary definition and utilities. */ + +#ifndef BROTLI_COMMON_SHARED_DICTIONARY_H_ +#define BROTLI_COMMON_SHARED_DICTIONARY_H_ + +#include +#include + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#define SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH 4 +#define SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH 31 +#define SHARED_BROTLI_NUM_DICTIONARY_CONTEXTS 64 +#define SHARED_BROTLI_MAX_COMPOUND_DICTS 15 + +/** + * Opaque structure that holds shared dictionary data. + * + * Allocated and initialized with ::BrotliSharedDictionaryCreateInstance. + * Cleaned up and deallocated with ::BrotliSharedDictionaryDestroyInstance. + */ +typedef struct BrotliSharedDictionaryStruct BrotliSharedDictionary; + +/** + * Input data type for ::BrotliSharedDictionaryAttach. + */ +typedef enum BrotliSharedDictionaryType { + /** Raw LZ77 prefix dictionary. */ + BROTLI_SHARED_DICTIONARY_RAW = 0, + /** Serialized shared dictionary. + * + * DO NOT USE: methods accepting this value will fail. + */ + BROTLI_SHARED_DICTIONARY_SERIALIZED = 1 +} BrotliSharedDictionaryType; + +/** + * Creates an instance of ::BrotliSharedDictionary. + * + * Fresh instance has default word dictionary and transforms + * and no LZ77 prefix dictionary. + * + * @p alloc_func and @p free_func @b MUST be both zero or both non-zero. In the + * case they are both zero, default memory allocators are used. @p opaque is + * passed to @p alloc_func and @p free_func when they are called. @p free_func + * has to return without doing anything when asked to free a NULL pointer. + * + * @param alloc_func custom memory allocation function + * @param free_func custom memory free function + * @param opaque custom memory manager handle + * @returns @c 0 if instance can not be allocated or initialized + * @returns pointer to initialized ::BrotliSharedDictionary otherwise + */ +BROTLI_COMMON_API BrotliSharedDictionary* BrotliSharedDictionaryCreateInstance( + brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque); + +/** + * Deinitializes and frees ::BrotliSharedDictionary instance. + * + * @param dict shared dictionary instance to be cleaned up and deallocated + */ +BROTLI_COMMON_API void BrotliSharedDictionaryDestroyInstance( + BrotliSharedDictionary* dict); + +/** + * Attaches dictionary to a given instance of ::BrotliSharedDictionary. + * + * Dictionary to be attached is represented in a serialized format as a region + * of memory. + * + * Provided data it partially referenced by a resulting (compound) dictionary, + * and should be kept untouched, while at least one compound dictionary uses it. + * This way memory overhead is kept minimal by the cost of additional resource + * management. + * + * @param dict dictionary to extend + * @param type type of dictionary to attach + * @param data_size size of @p data + * @param data serialized dictionary of type @p type, with at least @p data_size + * addressable bytes + * @returns ::BROTLI_TRUE if provided dictionary is successfully attached + * @returns ::BROTLI_FALSE otherwise + */ +BROTLI_COMMON_API BROTLI_BOOL BrotliSharedDictionaryAttach( + BrotliSharedDictionary* dict, BrotliSharedDictionaryType type, + size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]); + +#if defined(__cplusplus) || defined(c_plusplus) +} /* extern "C" */ +#endif + +#endif /* BROTLI_COMMON_SHARED_DICTIONARY_H_ */ diff --git a/packages/runtime/vendor/brotli/c/include/brotli/types.h b/packages/runtime/vendor/brotli/c/include/brotli/types.h new file mode 100644 index 000000000..2dc61ff40 --- /dev/null +++ b/packages/runtime/vendor/brotli/c/include/brotli/types.h @@ -0,0 +1,83 @@ +/* Copyright 2013 Google Inc. All Rights Reserved. + + Distributed under MIT license. + See file LICENSE for detail or copy at https://opensource.org/licenses/MIT +*/ + +/** + * @file + * Common types used in decoder and encoder API. + */ + +#ifndef BROTLI_COMMON_TYPES_H_ +#define BROTLI_COMMON_TYPES_H_ + +#include /* IWYU pragma: export */ + +#if defined(_MSC_VER) && (_MSC_VER < 1600) +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; +#else +#include /* IWYU pragma: export */ +#endif /* defined(_MSC_VER) && (_MSC_VER < 1600) */ + +/** + * A portable @c bool replacement. + * + * ::BROTLI_BOOL is a "documentation" type: actually it is @c int, but in API it + * denotes a type, whose only values are ::BROTLI_TRUE and ::BROTLI_FALSE. + * + * ::BROTLI_BOOL values passed to Brotli should either be ::BROTLI_TRUE or + * ::BROTLI_FALSE, or be a result of ::TO_BROTLI_BOOL macros. + * + * ::BROTLI_BOOL values returned by Brotli should not be tested for equality + * with @c true, @c false, ::BROTLI_TRUE, ::BROTLI_FALSE, but rather should be + * evaluated, for example: @code{.cpp} + * if (SomeBrotliFunction(encoder, BROTLI_TRUE) && + * !OtherBrotliFunction(decoder, BROTLI_FALSE)) { + * bool x = !!YetAnotherBrotliFunction(encoder, TO_BROLTI_BOOL(2 * 2 == 4)); + * DoSomething(x); + * } + * @endcode + */ +#define BROTLI_BOOL int +/** Portable @c true replacement. */ +#define BROTLI_TRUE 1 +/** Portable @c false replacement. */ +#define BROTLI_FALSE 0 +/** @c bool to ::BROTLI_BOOL conversion macros. */ +#define TO_BROTLI_BOOL(X) (!!(X) ? BROTLI_TRUE : BROTLI_FALSE) + +#define BROTLI_MAKE_UINT64_T(high, low) ((((uint64_t)(high)) << 32) | low) + +#define BROTLI_UINT32_MAX (~((uint32_t)0)) +#define BROTLI_SIZE_MAX (~((size_t)0)) + +/** + * Allocating function pointer type. + * + * @param opaque custom memory manager handle provided by client + * @param size requested memory region size; can not be @c 0 + * @returns @c 0 in the case of failure + * @returns a valid pointer to a memory region of at least @p size bytes + * long otherwise + */ +typedef void* (*brotli_alloc_func)(void* opaque, size_t size); + +/** + * Deallocating function pointer type. + * + * This function @b SHOULD do nothing if @p address is @c 0. + * + * @param opaque custom memory manager handle provided by client + * @param address memory region pointer returned by ::brotli_alloc_func, or @c 0 + */ +typedef void (*brotli_free_func)(void* opaque, void* address); + +#endif /* BROTLI_COMMON_TYPES_H_ */ diff --git a/packages/threads/package.json b/packages/threads/package.json index a37a3ba82..c29967cc6 100644 --- a/packages/threads/package.json +++ b/packages/threads/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/threads", - "version": "0.4.3", + "version": "0.4.4", "description": "Zero-copy publication of immutable object graphs to worker threads (scriptc), with a deep-freezing Node.js implementation", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/packages/types/package.json b/packages/types/package.json index 906c68dec..db88b4b2f 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@scriptc/types", - "version": "0.4.3", + "version": "0.4.4", "description": "Contract types for scriptc: type-only annotations (Int32, NoThrow, Immutable) that scriptc checks and optimizes, with no runtime semantics", "license": "Apache-2.0", "homepage": "https://scriptc.dev", diff --git a/scripts/bench-runtime.mjs b/scripts/bench-runtime.mjs index 61134fa4c..b45e3ebdf 100644 --- a/scripts/bench-runtime.mjs +++ b/scripts/bench-runtime.mjs @@ -40,6 +40,8 @@ const { values } = parseArgs({ layouts: { type: "string", default: "1" }, "baseline-optimization": { type: "string", default: "release" }, "candidate-optimization": { type: "string", default: "release" }, + "baseline-target-cpu": { type: "string" }, + "candidate-target-cpu": { type: "string" }, json: { type: "string" }, "no-lock": { type: "boolean", default: false }, node: { type: "boolean", default: true }, @@ -51,6 +53,7 @@ if (values.help) { console.log(`Usage: node scripts/bench-runtime.mjs [--candidate=] [--baseline=] [--workloads=a,b] [--runs=15] [--warmup=2] [--timeout=120] [--layouts=1] [--json=] [--baseline-optimization=release] [--candidate-optimization=release] + [--baseline-target-cpu=] [--candidate-target-cpu=] [--no-lock] [--no-node] [--keep] Each checkout must have a built CLI (packages/cli/dist/bootstrap.js) and native @@ -69,7 +72,10 @@ Workload names are the file names in benchmarks/runtime/workloads/*.json; for ex --baseline-optimization/--candidate-optimization pick each contender's --optimization posture (default release). The same checkout may be both contenders, e.g. --baseline=. --candidate-optimization=speed compares speed with -release. cold_build_ms records each contender's first, uncached build.`); +release. --baseline-target-cpu/--candidate-target-cpu pass --target-cpu to each +contender's builds, e.g. --baseline=. --candidate-target-cpu=x86-64-v3 compares +x86-64-v3 code with the baseline. cold_build_ms records each contender's first, +uncached build.`); process.exit(0); } const runs = Number(values.runs); @@ -428,7 +434,7 @@ function revision(root) { }); return r.stdout.trim() + (dirty.stdout.trim() ? "+dirty" : ""); } -function build(label, root, workload, layout, optimization) { +function build(label, root, workload, layout, optimization, targetCpu) { const cli = cliFor(root); const out = join(work, label, layout === 0 ? workload.name : `${workload.name}.layout${layout}`); mkdirSync(dirname(out), { recursive: true }); @@ -444,7 +450,15 @@ function build(label, root, workload, layout, optimization) { const entry = join(suiteRoot, workload.entry); const result = run( process.execPath, - [cli, "build", entry, `--optimization=${optimization}`, "-o", out], + [ + cli, + "build", + entry, + `--optimization=${optimization}`, + ...(targetCpu === undefined ? [] : [`--target-cpu=${targetCpu}`]), + "-o", + out, + ], { env, timeout: 900_000, @@ -467,6 +481,7 @@ const contenders = [ label: "baseline", root: resolve(values.baseline), optimization: values["baseline-optimization"], + targetCpu: values["baseline-target-cpu"], }, ] : []), @@ -474,6 +489,7 @@ const contenders = [ label: "candidate", root: resolve(values.candidate), optimization: values["candidate-optimization"], + targetCpu: values["candidate-target-cpu"], }, ]; const report = { @@ -580,7 +596,7 @@ try { entry.results[c.label] = result; result.binaries = []; for (let layout = 0; layout < layouts && result.status === undefined; layout++) { - const built = build(c.label, c.root, w, layout, c.optimization); + const built = build(c.label, c.root, w, layout, c.optimization, c.targetCpu); result.build_ms += Math.round(built.buildMs); if (layout === 0) result.cold_build_ms = Math.round(built.buildMs); if (!built.ok) { diff --git a/scripts/ci-test-plan.mjs b/scripts/ci-test-plan.mjs index 2b76b52d6..184f04d1c 100644 --- a/scripts/ci-test-plan.mjs +++ b/scripts/ci-test-plan.mjs @@ -42,22 +42,38 @@ export const testCosts = JSON.parse( readFileSync(new URL("./ci-test-costs.json", import.meta.url), "utf8"), ); +// Side-queue files whose process tree, run alone, peaks far above a plain +// vitest run (about 1 GB): megabytes at the peak, measured with CI's settings. +// They run beside the corpus task's three workers, so no two of them share a +// shard while there are shards without one. +export const memoryHeavyFiles = { + "tests/harness/decl-boundary.test.ts": 1838, +}; + // The shard (1-based) of each measured side-queue file and isolated suite: // longest first to the shard with the least work so far, counting about a // second per file for vitest to import it. Ties go to the highest shard, so the // longest files start from the last shard while the cost-balanced corpus and // three.js cases (tests/harness/shard.ts) place their longest from the first. -// An isolated suite without a measurement weighs as much as the median -// measured file. Files without a measurement are left to vitest's --shard, -// which splits them by count. +// An isolated suite or memory-heavy file without a measurement weighs as much +// as the median measured file. Memory-heavy files are placed after the others, +// each on the shard with the least memory-heavy work so far and, among those, +// the least work. Files without a +// measurement are left to vitest's --shard, which splits them by count. export function sideOwners(flavor, count) { const costs = testCosts[flavor]; const known = Object.values(costs).sort((a, b) => a - b); const median = known.length === 0 ? 0 : known[Math.floor(known.length / 2)]; const weight = (file) => (costs[file] ?? median) + 1000; - const files = [...new Set([...Object.keys(costs), ...isolatedFiles.map(([, file]) => file)])]; + const heavy = Object.keys(memoryHeavyFiles).sort( + (a, b) => memoryHeavyFiles[b] - memoryHeavyFiles[a] || (a < b ? -1 : a > b ? 1 : 0), + ); + const files = [ + ...new Set([...Object.keys(costs), ...isolatedFiles.map(([, file]) => file)]), + ].filter((file) => !(file in memoryHeavyFiles)); files.sort((a, b) => weight(b) - weight(a) || (a < b ? -1 : a > b ? 1 : 0)); const loads = new Array(count).fill(0); + const memory = new Array(count).fill(0); const owners = new Map(); for (const file of files) { let lightest = count - 1; @@ -66,6 +82,18 @@ export function sideOwners(flavor, count) { loads[lightest] += weight(file); owners.set(file, lightest + 1); } + for (const file of heavy) { + let lightest = count - 1; + for (let shard = count - 2; shard >= 0; shard--) + if ( + memory[shard] < memory[lightest] || + (memory[shard] === memory[lightest] && loads[shard] < loads[lightest]) + ) + lightest = shard; + memory[lightest] += memoryHeavyFiles[file]; + loads[lightest] += weight(file); + owners.set(file, lightest + 1); + } return owners; } diff --git a/tests/corpus/6343-inspect-class-values.ts b/tests/corpus/6343-inspect-class-values.ts new file mode 100644 index 000000000..5e9931c8c --- /dev/null +++ b/tests/corpus/6343-inspect-class-values.ts @@ -0,0 +1,31 @@ +// Classes reached through `unknown` print as Node prints them: +// `[class C]`, `[class C extends B]` with the runtime class's base, and +// `[class (anonymous)]`, at the top level and inside arrays and records. +import { inspect } from "node:util"; + +class A { + x = 1; +} +class B extends A { + y = 2; +} +class C extends B {} +class MyErr extends Error {} +const Anon = [class {}][0]!; +const Sub = class extends A {}; + +const a: unknown = A; +const b: unknown = B; +console.log(a, b); +console.log([a], { b }); +const values: unknown[] = [C, MyErr, Anon, Sub]; +console.log(values); +console.log(inspect({ deep: { values } }, { depth: 0 }), inspect(values, { depth: 0 })); +console.log(String(typeof values[0])); + +// A slot typed as the base holds a subclass at runtime. +const pick = (k: number): typeof A => (k === 0 ? A : k === 1 ? B : C); +for (let k = 0; k < 3; k++) { + const picked: unknown = pick(k); + console.log(k, picked); +} diff --git a/tests/corpus/6344-inspect-function-properties.cjs b/tests/corpus/6344-inspect-function-properties.cjs new file mode 100644 index 000000000..5cab04172 --- /dev/null +++ b/tests/corpus/6344-inspect-function-properties.cjs @@ -0,0 +1,62 @@ +'use strict'; +// Functions and classes reached as dynamic values print their enumerable +// own properties after the tag, as Node prints them: a class's static +// properties, properties assigned to a function, cycles through them, +// and `[Function]` past the depth limit, where a cycle still shows. +const util = require('util'); + +function f() {} +f.x = 1; +f.label = 'f'; +function g() {} +g.self = g; +function plain() {} +class A {} +class S extends A { + static get hidden() { + return 1; + } +} +S.count = 3; +function show(value) { + console.log(value); +} +show(f); +show(g); +show(S); +show(A); +show(plain); +function shallow(value) { + console.log(util.inspect({ value }, { depth: 0 })); +} +shallow(f); +shallow(S); +shallow(A); +console.log(util.inspect(g, { depth: 0 })); +shallow(g); + +// A class that reaches itself through its static properties is one cycle, +// whichever dynamic box of it the inspection meets. +class Loop { + static get hidden() { + return 1; + } +} +Loop.self = Loop; +Loop.label = 'loop'; +class Left { + static get hidden() { + return 2; + } +} +class Right { + static get hidden() { + return 3; + } +} +Left.other = Right; +Right.other = Left; +show(Loop); +show(Left); +show([Loop, Loop]); +show({ a: Left, b: Right }); diff --git a/tests/corpus/6357-format-o-hidden.ts b/tests/corpus/6357-format-o-hidden.ts new file mode 100644 index 000000000..44ed1d772 --- /dev/null +++ b/tests/corpus/6357-format-o-hidden.ts @@ -0,0 +1,35 @@ +// util.format's %o over values reached through `unknown` renders with +// showHidden, as Node does: arrays show their hidden `[length]` (with +// Node's grouping), at every depth, inside Maps and records too, ahead of +// an array's named properties. +import { format } from "node:util"; +const cases: [string, unknown][] = [ + ["ten", Array.from({ length: 10 }, (_, i) => i)], + ["wide", Array.from({ length: 120 }, (_, i) => i)], + ["hundred", Array.from({ length: 100 }, (_, i) => i)], + ["hundred-one", Array.from({ length: 101 }, (_, i) => i)], + ["hundred-strs", Array.from({ length: 100 }, (_, i) => "s" + i)], + ["seven", ["aaaaaaaaaaaaaaaaaaaa", "b", "c", "d", "e", "f", "g"]], + ["strs", Array.from({ length: 30 }, (_, i) => "s" + i)], + ["holes", [1, , 3]], + ["empty", []], + ["nested", { list: [[]], m: new Map([[1, [2]]]) }], + ["deep", [[[[[[1]]]]]]], + ["date", [new Date(0)]], +]; +for (const [k, v] of cases) console.log(k, format("%o", v)); +// The hidden `[length]` comes before an array's named properties, and the +// grid's last-entry rule counts both. +type Bag = Record; +const named = [1, 2]; +(named as unknown as Bag).foo = "x"; +const tagged = Array.from({ length: 100 }, (_, i) => i); +(tagged as unknown as Bag).tag = "t"; +const bare: number[] = []; +(bare as unknown as Bag).k = 1; +for (const [k, v] of [ + ["named", named], + ["tagged", tagged], + ["bare", bare], +] as [string, unknown][]) + console.log(k, format("%o", v)); diff --git a/tests/corpus/6358-format-o-hidden-js.cjs b/tests/corpus/6358-format-o-hidden-js.cjs new file mode 100644 index 000000000..df54b2714 --- /dev/null +++ b/tests/corpus/6358-format-o-hidden-js.cjs @@ -0,0 +1,9 @@ +'use strict'; +// %o shows an object's non-enumerable own properties as `[key]`, symbol +// keys included. +const util = require('util'); +const hidden = Object.defineProperty(JSON.parse('{"shown":1}'), 'secret', { value: [2], enumerable: false }); +Object.defineProperty(hidden, 'a-b', { value: 'x', enumerable: false }); +Object.defineProperty(hidden, Symbol('tag'), { value: 3, enumerable: false }); +console.log(util.format('%o and %O', hidden, hidden)); +console.log(util.format('%o', [hidden])); diff --git a/tests/corpus/6935-fs-url-paths-ordered.ts b/tests/corpus/6935-fs-url-paths-ordered.ts new file mode 100644 index 000000000..8d39c40ff --- /dev/null +++ b/tests/corpus/6935-fs-url-paths-ordered.ts @@ -0,0 +1,132 @@ +// URL paths that Node converts inside a try or after checking other +// arguments: existsSync answers false for a URL it cannot convert, the +// fs.promises functions return a promise rejected with the conversion's +// error, copyFileSync and renameSync check a string source before they +// convert a URL destination, and readFileSync checks a runtime encoding +// before it converts the URL. +import * as fs from "node:fs"; +import * as fsp from "node:fs/promises"; +import * as os from "node:os"; +import * as path from "node:path"; +import { pathToFileURL } from "node:url"; + +const dir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), "fs-url-ordered-"))); +const at = (name: string): URL => pathToFileURL(path.join(dir, name)); +const scheme = new URL("http://example.com/a.txt"); +const host = new URL("file://example.com/a.txt"); + +function report(label: string, error: unknown): void { + if (error instanceof Error) { + const code = (error as NodeJS.ErrnoException).code; + console.log(label, error.name, code, error.message.split(dir).join("")); + } +} + +function attempt(label: string, run: () => void): void { + try { + run(); + console.log(label, "returned"); + } catch (error) { + report(label, error); + } +} + +async function settle(label: string, run: () => Promise): Promise { + try { + await run(); + console.log(label, "fulfilled"); + } catch (error) { + report(label, error); + } +} + +async function main(): Promise { + fs.writeFileSync(at("a b.txt"), "hello"); + console.log(fs.existsSync(at("a b.txt")), fs.existsSync(at("missing"))); + console.log(fs.existsSync(scheme), fs.existsSync(host), fs.existsSync(new URL("file:///tmp/a%2Fb"))); + console.log(fs.existsSync(new URL("file:///tmp/a%00b"))); + + console.log(await fsp.readFile(at("a b.txt"), "utf8")); + console.log((await fsp.readFile(at("a b.txt"))).length); + await fsp.writeFile(at("w.txt"), "written"); + await fsp.appendFile(at("w.txt"), "!"); + console.log((await fsp.stat(at("w.txt"))).size, (await fsp.lstat(at("w.txt"))).isFile()); + await fsp.access(at("w.txt")); + await fsp.chmod(at("w.txt"), 0o644); + await fsp.truncate(at("w.txt"), 3); + await fsp.copyFile(at("w.txt"), at("copy.txt")); + await fsp.rename(at("copy.txt"), at("moved.txt")); + console.log(await fsp.readFile(at("moved.txt"), "utf8")); + await fsp.mkdir(at("sub/deep"), { recursive: true }); + console.log(await fsp.readdir(at("sub"))); + console.log(path.dirname(await fsp.mkdtemp(at("tmp-"))) === dir); + console.log((await fsp.realpath(at("sub/../sub"))).split(dir).join("")); + // An array literal lowers its elements more than once. + console.log([await fsp.realpath(at("sub"))].length, [fs.existsSync(scheme)][0]); + // A later argument with effects runs once per call there, and the call + // receives its value. + let dataCalls = 0; + const data = (): string => { + dataCalls++; + return `data ${dataCalls}`; + }; + console.log([await fsp.writeFile(at("w.txt"), data())].length, dataCalls); + console.log(await fsp.readFile(at("w.txt"), "utf8")); + const code = (error: unknown): string => String((error as { code?: string }).code); + const outcomes = [ + await fsp.writeFile(scheme, data()).then(() => "fulfilled", code), + await fsp.appendFile(at("w.txt"), data()).then(() => "fulfilled", code), + ]; + console.log(outcomes, dataCalls); + console.log(await fsp.readFile(at("w.txt"), "utf8")); + await fsp.rmdir(at("sub/deep")); + await fsp.unlink(at("moved.txt")); + await fsp.rm(at("w.txt")); + await fsp.rm(at("sub"), { recursive: true, force: true }); + console.log(fs.existsSync(at("sub"))); + + // The promise is returned; the error arrives as its rejection. + const pending = fsp.stat(scheme); + console.log("returned a promise"); + await pending.catch((error: unknown) => report("stat scheme", error)); + await settle("readFile host", () => fsp.readFile(host, "utf8")); + await settle("copyFile both", () => fsp.copyFile(scheme, host)); + await settle("rename dest", () => fsp.rename(at("a b.txt"), host)); + await settle("writeFile separator", () => fsp.writeFile(new URL("file:///tmp/a%2fb"), "x")); + await settle("unlink missing", () => fsp.unlink(at("missing"))); + await settle("rm scheme options", () => fsp.rm(scheme, { recursive: true, force: true })); + + // Arguments inside type-only wrappers are evaluated once. + let modeCalls = 0; + const countedMode = (): number => { + modeCalls++; + return 0o644; + }; + await settle("chmod satisfies", () => fsp.chmod(scheme, countedMode() satisfies number)); + await settle("chmod as", () => fsp.chmod(at("a b.txt"), countedMode() as number)); + await settle("chmod non-null", () => fsp.chmod(host, countedMode()!)); + console.log("mode calls", modeCalls); + await settle("copyFile as", () => fsp.copyFile(scheme, at("c.txt") as URL)); + await settle("copyFile dest as", () => fsp.copyFile(at("a b.txt"), host as URL)); + + attempt("copyFileSync source first", () => fs.copyFileSync("a\0b", scheme)); + attempt("copyFileSync dest", () => fs.copyFileSync(path.join(dir, "a b.txt"), host)); + attempt("renameSync source first", () => fs.renameSync("a\0b", host)); + fs.copyFileSync(path.join(dir, "a b.txt"), at("copied.txt")); + console.log(fs.readFileSync(at("copied.txt"), "utf8")); + + const encodings = ["utf8", "latin1", "base64", "bogus"]; + for (const encoding of encodings) { + attempt(`readFileSync ${encoding}`, () => { + console.log(fs.readFileSync(at("a b.txt"), encoding as BufferEncoding)); + }); + attempt(`readFileSync ${encoding} scheme`, () => { + console.log(fs.readFileSync(scheme, encoding as BufferEncoding)); + }); + } + + fs.rmSync(dir, { recursive: true, force: true }); + console.log("done", fs.existsSync(dir)); +} + +void main(); diff --git a/tests/corpus/7012-dictionary-views-keep-objects.ts b/tests/corpus/7012-dictionary-views-keep-objects.ts new file mode 100644 index 000000000..0df47cbb8 --- /dev/null +++ b/tests/corpus/7012-dictionary-views-keep-objects.ts @@ -0,0 +1,98 @@ +// A record or class instance converted to a string-keyed dictionary is +// the same object: writes through the dictionary reach it, and the +// dictionary is === to it. +const key = process.argv.length > 99 ? "never" : "added"; +type Point = { a: string }; + +// A type-literal record stored straight in a dictionary binding. +const direct: Point = { a: "x" }; +const directTable: Record = direct; +directTable[key] = "y"; +console.log(JSON.stringify(direct), (directTable as unknown) === direct); + +// The same record through a `{}` view. +const viewed: Point = { a: "x" }; +const view: {} = viewed; +const viewTable: Record = view; +viewTable[key] = "y"; +console.log(JSON.stringify(viewed)); + +// A declared index type, and a parameter. +interface Labels { + [name: string]: string; +} +function label(table: Labels, name: string): void { + table[name] = "set"; +} +const passed: Point = { a: "x" }; +label(passed, key); +console.log(JSON.stringify(passed)); + +// A `{}` parameter converted inside the function, called with a record +// and with a dictionary. +function viaView(value: {}): void { + const table: Record = value; + table[key] = "y"; +} +const record: Point = { a: "x" }; +viaView(record); +const dictionary: Record = { a: "x" }; +viaView(dictionary); +console.log(JSON.stringify(record), JSON.stringify(dictionary)); + +// A class instance through a `{}` view: a computed write replaces a method. +class Greeter { + name = "g"; + greet(): string { + return "hello " + this.name; + } +} +const greeter = new Greeter(); +const greeterView: {} = greeter; +const slots: Record = greeterView; +slots[process.argv.length > 99 ? "never" : "greet"] = "replaced"; +slots["name"] = "renamed"; +console.log(typeof greeter.greet, greeter.name, JSON.stringify(greeter)); +// A write under a runtime string key replaces a method too, and a direct +// call reaches the replacement, which is not a function. +class Counter { + n = 0; + tick(): number { + return ++this.n; + } +} +const counter = new Counter(); +const counterView: {} = counter; +const counterSlots: Record = counterView; +const methodKey: string = process.argv.length > 99 ? "never" : "tick"; +counterSlots[methodKey] = "replaced"; +try { + console.log(counter.tick()); +} catch (error) { + console.log((error as Error).name, (error as Error).message); +} +try { + console.log(greeter.greet()); +} catch (error) { + console.log((error as Error).name, (error as Error).message); +} + +// Deleting through the dictionary removes the key from the object. +const pruned: { a: string; b?: string } = { a: "x", b: "y" }; +const prunedTable: Record = pruned; +delete prunedTable[process.argv.length > 99 ? "never" : "b"]; +console.log(JSON.stringify(pruned), "b" in pruned); + +// A dictionary literal whose methods read `this` keeps its live object. +interface Table { + [key: string]: () => number; +} +const table: Table = { + base() { + return 2; + }, + twice() { + return this.base() * 2; + }, +}; +console.log(table.twice(), Object.keys(table).join(",")); diff --git a/tests/corpus/7013-dictionary-view-parameter.ts b/tests/corpus/7013-dictionary-view-parameter.ts new file mode 100644 index 000000000..2bfc34a76 --- /dev/null +++ b/tests/corpus/7013-dictionary-view-parameter.ts @@ -0,0 +1,30 @@ +// A record passed to a `{}` parameter and converted to a dictionary inside +// the function is the same object: the write through the dictionary +// reaches the caller's record. A dot write through a dictionary view of a +// class instance replaces its method. +const key = process.argv.length > 99 ? "never" : "added"; +function stamp(value: {}): void { + const table: Record = value; + table[key] = "y"; +} +const record: { a: string } = { a: "x" }; +stamp(record); +console.log(JSON.stringify(record), key in record); + +// A dot write through the dictionary view replaces a method too. +class Lamp { + on = false; + toggle(): boolean { + this.on = !this.on; + return this.on; + } +} +const lamp = new Lamp(); +const lampView: {} = lamp; +const lampSlots: Record = lampView; +lampSlots.toggle = "replaced"; +try { + console.log(lamp.toggle()); +} catch (error) { + console.log((error as Error).name, (error as Error).message); +} diff --git a/tests/corpus/7189-non-null-assertion-nullish-destination.ts b/tests/corpus/7189-non-null-assertion-nullish-destination.ts new file mode 100644 index 000000000..632655cff --- /dev/null +++ b/tests/corpus/7189-non-null-assertion-nullish-destination.ts @@ -0,0 +1,57 @@ +// `!` has no runtime effect: a value asserted non-null that still holds +// null or undefined reaches a return value, an arrow function's result or +// an argument whose declared type holds it (or is any or unknown), unchanged. +interface Shape { + size: number; +} + +const shapes = new Map(); +function shapeOf(key: string): Shape | null { + if (shapes.has(key)) return shapes.get(key)!; + const result = key.length > 3 ? { size: key.length } : null; + shapes.set(key, result); + return result; +} +console.log(shapeOf("ab"), shapeOf("abcd")); +console.log(shapeOf("ab"), shapeOf("abcd"), shapes.size); + +const counts = new Map([["a", 1]]); +function countOf(key: string): number | undefined { + return counts.get(key)!; +} +console.log(countOf("a"), countOf("b")); + +function describe(shape: Shape | null): string { + return shape === null ? "none" : `size ${shape.size}`; +} +console.log(describe(shapes.get("ab")!), describe(shapes.get("abcd")!)); + +class Slot { + readonly label: string; + constructor(shape: Shape | null) { + this.label = shape === null ? "empty" : `slot ${shape.size}`; + } +} +console.log(new Slot(shapes.get("ab")!).label, new Slot(shapes.get("abcd")!).label); + +const lookup = (key: string): Shape | null => shapes.get(key)!; +console.log(lookup("ab"), lookup("abcd")?.size); + +const names = new Map([["a", null], ["b", "bee"]]); +const amounts = new Map([["a", undefined], ["b", 2]]); +function kindOf(value: unknown): string { + return value === null ? "null" : typeof value; +} +console.log(String(names.get("a")!), String(names.get("b")!)); +console.log(Number(amounts.get("a")!), Number(amounts.get("b")!)); +console.log(kindOf(names.get("a")!), kindOf(amounts.get("a")!), kindOf(names.get("b")!)); + +// An optional parameter of a standard library method keeps the checked +// narrowing: `decode(input?)` reads the asserted Uint8Array. +const chunks = new Map([["a", new TextEncoder().encode("chunk")]]); +interface Read { + done: boolean; + value?: Uint8Array; +} +const read: Read = { done: false, value: chunks.get("a") }; +console.log(new TextDecoder().decode(chunks.get("a")!), new TextDecoder().decode(read.value!).slice(0, 3)); diff --git a/tests/corpus/7392-non-null-operands.ts b/tests/corpus/7392-non-null-operands.ts new file mode 100644 index 000000000..60928ddb6 --- /dev/null +++ b/tests/corpus/7392-non-null-operands.ts @@ -0,0 +1,137 @@ +// Non-null assertions on values that still hold undefined or null, used as +// operands of operators that convert them: arithmetic, comparisons, string +// conversion, Math functions, and loose equality with null. `!` +// performs no runtime check, so the operator sees undefined or null and +// converts it as JavaScript does. + +interface Settings { + limit?: number; + label?: string; + enabled?: boolean; + ratio: number | null; + note?: string | null; +} + +const empty: Settings = { ratio: null }; +const full: Settings = { limit: 4, label: "abc", enabled: true, ratio: 0.5, note: "n" }; +const counts: Record = { a: 1, b: 2 }; +const sizes = new Map([["small", 1]]); +const values = [3, 1, 4]; + +function show(v: unknown): string { + return Object.is(v, -0) ? "-0" : String(v); +} + +function line(label: string, parts: unknown[]): void { + console.log(label.padEnd(12), parts.map(show).join(" ")); +} + +for (const s of [empty, full]) { + const tag = s === empty ? "empty" : "full"; + line(`${tag} arith`, [ + s.limit! + 1, + s.limit! - 1, + s.limit! * 2, + s.limit! / 2, + s.limit! % 3, + s.limit! ** 2, + -s.limit!, + +s.limit!, + s.ratio! + 1, + s.ratio! * 4, + -s.ratio!, + s.limit! - s.ratio!, + ]); + line(`${tag} bits`, [s.limit! | 0, s.limit! & 6, s.limit! << 1, s.limit! >>> 0, ~s.limit!, s.ratio! ^ 1]); + line(`${tag} compare`, [ + s.limit! < 5, + s.limit! >= 0, + s.ratio! < 1, + s.ratio! > -1, + s.limit! === 4, + s.limit! !== 4, + s.ratio! == 0, + s.label! < "b", + s.label! >= "a", + s.label! === "abc", + s.enabled! === true, + s.limit! > s.ratio!, + ]); + line(`${tag} strings`, [ + `${s.limit!}`, + `${s.ratio!}`, + `${s.enabled!}`, + `[${s.label!}]`, + `${s.note!}`, + "n=" + s.limit!, + s.limit! + "!", + s.label! + "?", + "<" + s.note!, + ]); + line(`${tag} convert`, [ + Math.round(s.limit!), + Math.max(s.limit!, 1), + Math.min(s.ratio!, 1), + !s.enabled!, + !s.ratio!, + ]); +} + +line("record", [counts["z"]! + 1, counts["a"]! + 1, counts["z"]! > 0, `${counts["z"]!}`]); +line("map", [sizes.get("large")! * 2, sizes.get("small")! * 2, `${sizes.get("large")!}`]); +line("find", [values.find((v) => v > 9)! + 1, values.find((v) => v > 3)! + 1]); + +let total = 0; +let text = ""; +let mask = 7; +for (const key of ["a", "b", "c", "a"]) { + total += counts[key]!; + text += counts[key]!; + text += ","; + mask &= counts[key]!; +} +line("compound", [total, text, mask]); + +const tally: Record = {}; +for (const word of ["x", "y", "x"]) tally[word] = tally[word]! + 1; +line("tally", [tally["x"], tally["y"]]); + +type Cell = number | string | null | undefined; +for (const cell of [3, "4", null, undefined] as Cell[]) { + const m = new Map([["k", cell]]); + line("cell", [`${m.get("k")!}`, m.get("k")! === 3, String(m.get("k")!)]); +} + +// Loose equality with null tests both unit arms of a value read once. +const optional = new Map([["one", 1], ["none", null]]); +let reads = 0; +function lookup(key: string): string | null | undefined { + reads++; + return key === "a" ? "x" : key === "b" ? null : undefined; +} +for (const key of ["one", "none", "missing"]) { + line(`loose ${key}`, [optional.get(key)! == null, optional.get(key)! != undefined, optional.get(key)! == 1]); +} +line("loose call", [lookup("a") == null, lookup("b") == null, lookup("c") != null, reads]); + +// `+` with an untyped partner concatenates or adds depending on what the +// partner holds when it runs. +const untypedText: any = "x"; +const untypedNumber: any = 5; +const untypedObject: any = { toString: () => "obj" }; +for (const s of [empty, full]) { + let joined: any = "t"; + let summed: any = 1; + joined += s.limit!; + summed += s.limit!; + line(`untyped ${s === empty ? "empty" : "full"}`, [ + s.limit! + untypedText, + untypedText + s.limit!, + s.limit! + untypedNumber, + untypedNumber + s.limit!, + s.label! + untypedText, + s.limit! + untypedObject, + joined, + summed, + ]); +} diff --git a/tests/corpus/7394-non-null-typed-array-reads.ts b/tests/corpus/7394-non-null-typed-array-reads.ts new file mode 100644 index 000000000..bab1bcf9c --- /dev/null +++ b/tests/corpus/7394-non-null-typed-array-reads.ts @@ -0,0 +1,80 @@ +// Non-null assertions on typed-array element reads. `!` performs no +// runtime check: an index outside the array reads undefined, as in Node, +// wherever the use tells undefined from NaN (equality, string conversion, +// typeof, Object.is, an array element), and NaN where it converts the value +// to a number. + +const int32 = new Int32Array([1, -2, 3]); +const float64 = new Float64Array([1.5, NaN, -0]); +const uint8 = new Uint8Array([7, 255]); + +function show(v: unknown): string { + return Object.is(v, -0) ? "-0" : String(v); +} + +function line(label: string, parts: unknown[]): void { + console.log(label.padEnd(12), parts.map(show).join(" ")); +} + +for (const k of [0, 1, 2, 3, -1, 1.5]) { + line(`int32 ${k}`, [ + int32[k]! === int32[k]!, + int32[k]! !== int32[0]!, + int32[k]! === undefined, + int32[k]! == null, + Object.is(int32[k]!, undefined), + typeof int32[k]!, + `${int32[k]!}`, + "v=" + int32[k]!, + String(int32[k]!), + int32[k]! + 1, + int32[k]! < 2, + [int32[k]!].length, + ]); + line(`float64 ${k}`, [ + float64[k]! === float64[k]!, + float64[k]! === undefined, + Object.is(float64[k]!, NaN), + typeof float64[k]!, + `${float64[k]!}`, + float64[k]! * 2, + -float64[k]!, + ]); + line(`uint8 ${k}`, [ + uint8[k]! === uint8[k]!, + uint8[k]! == undefined, + typeof uint8[k]!, + `${uint8[k]!}`, + uint8[k]! | 0, + uint8[k]! > 100, + ]); +} + +const optional: number | undefined = uint8[5]!; +const listed = [int32[9]!, float64[0]!]; +line("slots", [optional, listed[0], listed[1], listed.length]); + +let total = 0; +for (let i = 0; i <= int32.length; i++) total += int32[i]!; +line("sum", [total]); + +// Arrays that store an asserted read past the end hold undefined, which +// their callbacks see. +const pushed: number[] = []; +pushed.push(int32[7]!); +pushed.push(uint8[1]!); +const literal = [float64[5]!, float64[0]!]; +const assigned: number[] = [1, 2]; +assigned[0] = uint8[9]!; +let visited = 0; +pushed.forEach((v) => { + visited += v; +}); +line("callbacks", [ + pushed.map((v) => v * 2).join(","), + visited, + literal.map((v) => typeof v).join(","), + literal.filter((v) => v === undefined).length, + assigned.map((v) => v + 1).join(","), + assigned.some((v) => v === undefined), +]); diff --git a/tests/corpus/7453-untyped-overload-results.cjs b/tests/corpus/7453-untyped-overload-results.cjs new file mode 100644 index 000000000..21923827d --- /dev/null +++ b/tests/corpus/7453-untyped-overload-results.cjs @@ -0,0 +1,85 @@ +// An untyped argument can match any overload of a call at run time. The +// result follows the overload the value selects, through bindings, +// destructuring and function returns. +const crypto = require("crypto"); +const fs = require("fs"); +const os = require("os"); +const path = require("path"); + +const ecPair = (options) => crypto.generateKeyPairSync("ec", options); +const objects = ecPair({ namedCurve: "P-256" }); +console.log(typeof objects.privateKey, objects.privateKey.type, objects.publicKey.asymmetricKeyType); +const pem = ecPair({ + namedCurve: "P-256", + publicKeyEncoding: { type: "spki", format: "pem" }, + privateKeyEncoding: { type: "pkcs8", format: "pem" }, +}); +console.log(typeof pem.privateKey, pem.publicKey.split("\n")[0]); + +function privateKeyKind(options) { + const pair = crypto.generateKeyPairSync("ec", options); + return typeof pair.privateKey; +} +console.log(privateKeyKind({ namedCurve: "P-384" })); + +function spread(options) { + const { privateKey, publicKey } = crypto.generateKeyPairSync("ec", { + namedCurve: "P-256", + ...options, + }); + return [typeof privateKey, Buffer.isBuffer(publicKey)]; +} +console.log(spread({}), spread({ publicKeyEncoding: { type: "spki", format: "der" } })); + +const digest = (encoding) => crypto.createHash("sha256").update("x").digest(encoding); +console.log(typeof digest("hex"), Buffer.isBuffer(digest(undefined)), digest(undefined).length); +const hmac = (encoding) => crypto.createHmac("sha256", "k").update("v").digest(encoding); +console.log(hmac("base64"), Buffer.isBuffer(hmac())); +function digestLength(encoding) { + let value = crypto.createHash("sha1").update("y").digest(encoding); + return Buffer.isBuffer(value) ? `buffer ${value.length}` : `string ${value.length}`; +} +console.log(digestLength(undefined), digestLength("hex")); +async function digestLater(encoding) { + return crypto.createHash("md5").update("z").digest(encoding); +} + +const key = crypto.generateKeyPairSync("ed25519").publicKey; +const exported = (options) => key.export(options); +console.log( + Buffer.isBuffer(exported({ format: "der", type: "spki" })), + typeof exported({ format: "pem", type: "spki" }), + exported({ format: "jwk" }).kty, +); + +const file = path.join(fs.mkdtempSync(path.join(os.tmpdir(), "overloads-")), "text.txt"); +fs.writeFileSync(file, "hello"); +const read = (options) => fs.readFileSync(file, options); +const text = read("utf8"); +const bytes = read(undefined); +const latin1 = read({ encoding: "latin1" }); +console.log(text, Buffer.isBuffer(bytes), bytes.length, latin1); +console.log(read("utf8"), read({ encoding: "hex" })); + +/** + * @overload + * @param {string} value + * @returns {string} + */ +/** + * @overload + * @param {number} value + * @returns {number} + */ +/** @param {string | number} value */ +function same(value) { + return value; +} +const viaSame = (value) => same(value); +console.log(typeof viaSame("s"), typeof viaSame(3), viaSame(3) + 1); + +(async () => { + const later = await digestLater(undefined); + console.log(Buffer.isBuffer(later), typeof (await digestLater("hex"))); + fs.rmSync(path.dirname(file), { recursive: true }); +})(); diff --git a/tests/corpus/7623-key-order-javascript-built-records/lib.js b/tests/corpus/7623-key-order-javascript-built-records/lib.js index 4ff312846..a981505fc 100644 --- a/tests/corpus/7623-key-order-javascript-built-records/lib.js +++ b/tests/corpus/7623-key-order-javascript-built-records/lib.js @@ -1,11 +1,18 @@ // Records built in JavaScript in another key order than the TypeScript // literals of the same type: a replacement method installed through a -// computed key, and a function stored on the global object, read through a -// typed view, that calls a callback inside its options record. +// computed key (beside another computed write that installs a function +// returning a primitive), and a function stored on the global object, read +// through a typed view, that calls a callback inside its options record. export function install(target, name) { target[name] = () => ({ a: 1, b: 2 }); } +// A later computed write of a function that returns a primitive does not +// hide the record-returning one above. +export function installLabel(target, name) { + target[name] = () => "label"; +} + globalThis.__eachRow = function (options) { options.visit({ x: 5, y: 6 }); }; diff --git a/tests/corpus/7623-key-order-javascript-built-records/main.ts b/tests/corpus/7623-key-order-javascript-built-records/main.ts index ae4876131..1615351d7 100644 --- a/tests/corpus/7623-key-order-javascript-built-records/main.ts +++ b/tests/corpus/7623-key-order-javascript-built-records/main.ts @@ -1,7 +1,7 @@ // Copies and enumerations of records JavaScript builds follow the order // JavaScript wrote, also when the TypeScript literals of the type write // another order and spread their own type. Each case uses its own type. -import { install } from "./lib.js"; +import { install, installLabel } from "./lib.js"; interface Pair { a: number; @@ -39,6 +39,9 @@ showPair("method", store.get()); showPair("self copy", { ...store.get(), b: 3 }); install(store, "get"); showPair("replaced", store.get()); +const labels: { label(): string } = { label: () => "plain" }; +installLabel(labels, "label"); +console.log(labels.label()); // A JavaScript function, checked into a typed slot, calls a native callback // it receives inside its options record with a record it builds. diff --git a/tests/corpus/7624-key-order-boxed-callback-records/lib.js b/tests/corpus/7624-key-order-boxed-callback-records/lib.js new file mode 100644 index 000000000..47ba5b99c --- /dev/null +++ b/tests/corpus/7624-key-order-boxed-callback-records/lib.js @@ -0,0 +1,7 @@ +// A JavaScript function that calls a callback inside its options object +// with records it builds, in another key order than the TypeScript literals +// of the callback's parameter type. +export function each(options) { + options.visit({ a: 1, b: 2 }); + options.visit({ a: 3, b: 4 }); +} diff --git a/tests/corpus/7624-key-order-boxed-callback-records/main.ts b/tests/corpus/7624-key-order-boxed-callback-records/main.ts new file mode 100644 index 000000000..4cdfeff37 --- /dev/null +++ b/tests/corpus/7624-key-order-boxed-callback-records/main.ts @@ -0,0 +1,27 @@ +// A native callback handed to JavaScript inside an options record receives +// records JavaScript builds: copies and enumerations of them follow the +// order JavaScript wrote, also when the TypeScript literals of the type +// write another order and spread their own type. +import { each } from "./lib.js"; + +interface Row { + a: number; + b: number; +} + +function show(label: string, row: Row): void { + const copy = { ...row }; + console.log(label, Object.keys(row).join(), JSON.stringify(copy), Object.keys(copy).join()); +} + +const literal: Row = { b: 20, a: 10 }; +show("literal", literal); +show("self copy", { ...literal, b: 21 }); +const seen: Row[] = []; +each({ + visit: (row: Row) => { + seen.push(row); + show("callback", row); + }, +}); +console.log(JSON.stringify(seen), JSON.stringify(seen.map((row) => ({ ...row, a: row.a * 2 })))); diff --git a/tests/corpus/7680-typed-array-search.ts b/tests/corpus/7680-typed-array-search.ts new file mode 100644 index 000000000..7672c3712 --- /dev/null +++ b/tests/corpus/7680-typed-array-search.ts @@ -0,0 +1,70 @@ +// TypedArray.prototype.indexOf, lastIndexOf and includes on every numeric +// element kind: strict equality (NaN never found) for indexOf/lastIndexOf, +// SameValueZero (NaN found, -0 equals 0) for includes, and fromIndex as +// ToIntegerOrInfinity, counted from the end when negative. +const bytes = new Uint8Array([1, 2, 10, 3, 10, 255]); +console.log("u8", bytes.indexOf(10), bytes.indexOf(10, 3), bytes.indexOf(10, 5), bytes.lastIndexOf(10)); +console.log("u8 from", bytes.indexOf(10, -2), bytes.indexOf(10, -100), bytes.indexOf(1, Infinity), bytes.indexOf(10, 2.9)); +console.log("u8 last", bytes.lastIndexOf(10, 3), bytes.lastIndexOf(10, -3), bytes.lastIndexOf(1, -100), bytes.lastIndexOf(255, 99)); +console.log("u8 values", bytes.indexOf(256 + 10), bytes.indexOf(-246), bytes.indexOf(10.5), bytes.includes(255), bytes.includes(0)); +console.log("u8 includes from", bytes.includes(1, 1), bytes.includes(255, -1), bytes.includes(2, -5)); + +const clamped = new Uint8ClampedArray([0, 300, -5, 127.5]); +console.log("u8c", clamped.indexOf(255), clamped.indexOf(0, 1), clamped.lastIndexOf(0), clamped.indexOf(128)); + +const signed = new Int8Array([-1, 127, -128, 0]); +console.log("i8", signed.indexOf(-1), signed.indexOf(255), signed.indexOf(-128), signed.lastIndexOf(0)); + +const shorts = new Int16Array([5, -300, 5, 7]); +const ushorts = new Uint16Array([65535, 1, 65535]); +console.log("16", shorts.indexOf(-300), shorts.lastIndexOf(5), ushorts.indexOf(-1), ushorts.lastIndexOf(65535, 1)); + +const ints = new Int32Array([-2147483648, 0, 2147483647, 0]); +const uints = new Uint32Array([4294967295, 3]); +console.log("32", ints.indexOf(2147483647), ints.lastIndexOf(0), uints.indexOf(4294967295), uints.includes(-1)); + +const floats = new Float64Array([1.5, NaN, -0, 0, Infinity]); +console.log("f64", floats.indexOf(NaN), floats.lastIndexOf(NaN), floats.includes(NaN), floats.indexOf(0), floats.indexOf(-0)); +console.log("f64 more", floats.lastIndexOf(0), floats.indexOf(Infinity), floats.includes(-Infinity), floats.includes(NaN, 2)); + +const singles = new Float32Array([1.1, 0.5, NaN]); +console.log("f32", singles.indexOf(1.1), singles.indexOf(Math.fround(1.1)), singles.indexOf(0.5), singles.includes(NaN), singles.indexOf(NaN)); + +const empty = new Float64Array(0); +console.log("empty", empty.indexOf(0), empty.lastIndexOf(0), empty.includes(0), empty.includes(0, -1)); + +// Views search their own window of the buffer. +const buffer = new ArrayBuffer(16); +const whole = new Uint8Array(buffer); +whole.set([9, 9, 1, 2, 9, 3, 9, 9]); +const view = new Uint8Array(buffer, 2, 4); +const sub = whole.subarray(3, 6); +console.log("views", view.indexOf(9), view.lastIndexOf(9), view.indexOf(1), sub.indexOf(9), sub.includes(1), sub.lastIndexOf(3)); +const words = new Uint16Array(buffer, 2, 3); +console.log("word view", words.indexOf(0x0201), words.length); + +// Shared memory searches the same way. +const shared = new Int32Array(new SharedArrayBuffer(16)); +shared[1] = 7; +shared[3] = 7; +console.log("shared", shared.indexOf(7), shared.lastIndexOf(7), shared.includes(0), shared.indexOf(7, 2)); + +// A loop that finds every occurrence, as a line splitter does. +const text = new TextEncoder().encode("one\ntwo\n\nthree\n"); +const lines: number[] = []; +for (let at = text.indexOf(10); at !== -1; at = text.indexOf(10, at + 1)) lines.push(at); +console.log("lines", lines.join(",")); + +// A Buffer passed as a Uint8Array keeps Buffer's search: a number needle +// is taken as a byte, and a NaN byteOffset searches the whole buffer. +function searchView(view: Uint8Array): string { + return [view.indexOf(97 + 256), view.lastIndexOf(98, NaN), view.includes(353), view.indexOf(98, -1)].join(","); +} +console.log(searchView(Buffer.from("abcab")), searchView(new Uint8Array([97, 98, 99, 97, 98]))); + +// An explicit undefined fromIndex converts to NaN, which searches from 0: +// lastIndexOf then looks at index 0 only. +const values = new Int16Array([3, 1, 3, 2, 3]); +const absent: number | undefined = process.argv.length > 99 ? 1 : undefined; +console.log("undefined from", values.indexOf(3, undefined), values.lastIndexOf(3, undefined), values.lastIndexOf(1, undefined), values.includes(2, undefined)); +console.log("maybe undefined from", values.indexOf(3, absent), values.lastIndexOf(3, absent), values.includes(1, absent)); diff --git a/tests/corpus/7681-typed-array-search-dynamic.mjs b/tests/corpus/7681-typed-array-search-dynamic.mjs new file mode 100644 index 000000000..643ba0cfa --- /dev/null +++ b/tests/corpus/7681-typed-array-search-dynamic.mjs @@ -0,0 +1,28 @@ +// TypedArray search on untyped values (parameters of untyped functions and +// object members): needles that are not numbers are never found (strict +// equality), fromIndex may be undefined, a string or a fraction, and +// Buffers keep their own indexOf, which wraps number needles and takes +// strings. +function views(bytes, floats, shorts) { + return { bytes, floats, shorts }; +} +const { bytes, floats, shorts } = views( + new Uint8Array([1, 2, 10, 3, 10]), + new Float64Array([0.5, NaN, -0]), + new Int16Array([-1, 300, -1]), +); +console.log(bytes.indexOf(10), bytes.indexOf(10, 3), bytes.lastIndexOf(10), bytes.includes(3), bytes.includes(4)); +console.log(bytes.lastIndexOf(1, undefined), bytes.lastIndexOf(10), bytes.indexOf(10, undefined), bytes.includes(1, undefined)); +console.log(bytes.indexOf(10, '3'), bytes.indexOf(10, 2.9), bytes.indexOf(10, -1), bytes.lastIndexOf(10, -2), bytes.indexOf(10, null)); +console.log(bytes.indexOf('10'), bytes.includes('1'), bytes.indexOf(10n), bytes.indexOf(), bytes.includes(), bytes.indexOf(266)); +console.log(floats.indexOf(NaN), floats.includes(NaN), floats.indexOf(0), floats.lastIndexOf(-0), floats.includes(0.5, 1)); +console.log(shorts.indexOf(-1), shorts.lastIndexOf(-1), shorts.indexOf(300, -2), shorts.includes(65535)); +const holder = { view: bytes.subarray(2) }; +console.log(holder.view.indexOf(10), holder.view.lastIndexOf(10), holder.view.includes(1)); +const buffer = Buffer.from([1, 2, 10, 3, 10]); +const boxed = [buffer]; +console.log(boxed[0].indexOf(10), boxed[0].indexOf(266), boxed[0].indexOf('\n'), boxed[0].includes(Buffer.from([3, 10]))); +console.log(boxed[0].subarray(3).indexOf(10), Buffer.isBuffer(boxed[0].subarray(3)), boxed[0].lastIndexOf(10, -2)); +let count = 0; +for (let at = bytes.indexOf(10); at !== -1; at = bytes.indexOf(10, at + 1)) count++; +console.log('count', count); diff --git a/tests/corpus/7682-constructor-function-globals.js b/tests/corpus/7682-constructor-function-globals.js new file mode 100644 index 000000000..58292e4ac --- /dev/null +++ b/tests/corpus/7682-constructor-function-globals.js @@ -0,0 +1,55 @@ +// Module bindings that hold `new F()` of an ordinary constructor function +// (const, let and var), read and reassigned by functions declared elsewhere +// in the module, such as the head and tail of a linked list. +'use strict'; +function Segment(prev) { + this.prev = prev; + this.next = null; + this.data = new Array(4); + this.pos = 0; +} +const head = new Segment(); +let current = head; +var spare = new Segment(head); + +function append(value) { + if (current.pos === current.data.length) { + current = current.next || (current.next = new Segment(current)); + } + current.data[current.pos++] = value; +} + +function collect() { + const out = []; + for (let node = head; node; node = node.next) out.push(node.data.slice(0, node.pos).join('')); + return out.join('|'); +} + +function reset() { + current = head; + for (let node = head; node; node = node.next) node.pos = 0; +} + +for (const ch of 'abcdefghij') append(ch); +console.log(collect(), current === head, current.prev === head.next ? 'two' : 'more'); +reset(); +append('z'); +console.log(collect(), current === head, head.next !== null); +console.log(spare.prev === head, spare instanceof Segment, typeof spare.data); +spare = new Segment(spare); +console.log(spare.prev.prev === head); + +function Counter(start) { + this.value = start; +} +Counter.prototype.bump = function () { + return ++this.value; +}; +let counter = new Counter(10); +function bumpTwice() { + counter.bump(); + return counter.bump(); +} +console.log(bumpTwice(), counter.value); +counter = new Counter(0); +console.log(bumpTwice()); diff --git a/tests/corpus/7714-zlib-brotli-compress.cjs b/tests/corpus/7714-zlib-brotli-compress.cjs new file mode 100644 index 000000000..9f12f35f8 --- /dev/null +++ b/tests/corpus/7714-zlib-brotli-compress.cjs @@ -0,0 +1,91 @@ +// zlib's Brotli compression over the vendored brotli 1.2.0, the version +// Node bundles: compressed bytes match Node's for the same parameters, and +// the options, errors, callback, promisified and stream forms follow Node. +const zlib = require("node:zlib"); +const { promisify } = require("node:util"); + +const text = Buffer.from("hello hello hello brotli ".repeat(20)); +const hex = (b) => b.toString("hex"); +const tryIt = (label, run) => { + try { + const r = run(); + console.log(label, "ok", Buffer.isBuffer(r) ? hex(r) : r); + } catch (e) { + console.log(label, e.name, e.code, e.errno, e.message); + } +}; + +console.log(hex(zlib.brotliCompressSync("")), hex(zlib.brotliCompressSync("a"))); +for (const quality of [0, 1, 4, 5, 9, 11]) { + const out = zlib.brotliCompressSync(text, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: quality } }); + console.log("quality", quality, out.length, hex(out)); +} +console.log("text mode", hex(zlib.brotliCompressSync(text, { params: { [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT } }))); +console.log("font mode", hex(zlib.brotliCompressSync(text, { params: { [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_FONT } }))); +console.log( + "window", + hex(zlib.brotliCompressSync(text, { + params: { [zlib.constants.BROTLI_PARAM_LGWIN]: 10, [zlib.constants.BROTLI_PARAM_SIZE_HINT]: text.length }, + })), +); +console.log("dictionary", hex(zlib.brotliCompressSync("hello world", { dictionary: Buffer.from("hello world") }))); +console.log("arraybuffer dictionary", hex(zlib.brotliCompressSync("hello world", { dictionary: new Uint8Array([104, 101, 108, 108, 111]).buffer }))); +console.log("finishFlush", hex(zlib.brotliCompressSync("hello", { finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH }))); +tryIt("boolean param", () => zlib.brotliCompressSync("x", { params: { [zlib.constants.BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING]: true } })); +tryIt("fractional quality", () => zlib.brotliCompressSync("hello hello hello", { params: { 1: 4.7 } })); +tryIt("negative quality", () => zlib.brotliCompressSync("hello hello hello", { params: { 1: -1 } })); +tryIt("quality above 11", () => zlib.brotliCompressSync("hello hello hello", { params: { 1: 12 } })); +tryIt("unknown param", () => zlib.brotliCompressSync("x", { params: { 9999: 1 } })); +tryIt("param 9", () => zlib.brotliCompressSync("x", { params: { 9: 0 } })); +tryIt("repeated param", () => zlib.brotliCompressSync("x", { params: { 1: 5, "01": 4 } })); +tryIt("fractional param key", () => zlib.brotliCompressSync("x", { params: { "1.5": 5 } })); +tryIt("negative param key", () => zlib.brotliCompressSync("x", { params: { "-1": 5 } })); +tryIt("string param value", () => zlib.brotliCompressSync("x", { params: { 1: "5" } })); +tryIt("string dictionary", () => zlib.brotliCompressSync("x", { dictionary: "abc" })); +tryIt("chunkSize", () => zlib.brotliCompressSync(text, { chunkSize: 10 })); +tryIt("flush", () => zlib.brotliCompressSync(text, { flush: 4 })); +tryIt("finishFlush range", () => zlib.brotliCompressSync(text, { finishFlush: 99 })); +tryIt("rejectGarbageAfterEnd", () => zlib.brotliCompressSync(text, { rejectGarbageAfterEnd: 1 })); +tryIt("maxOutputLength", () => zlib.brotliCompressSync(text, { maxOutputLength: 8 })); +tryIt("number input", () => zlib.brotliCompressSync(JSON.parse("5"))); + +zlib.brotliCompress(text, (err, out) => { + console.log("callback", err, hex(out)); + zlib.brotliCompress("abc", { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 2 } }, (err2, out2) => { + console.log("callback options", err2, hex(out2)); + promised(); + }); +}); + +function promised() { + const compress = promisify(zlib.brotliCompress); + compress("promised").then((out) => { + console.log("promisified", hex(out)); + streams(); + }); +} + +function streams() { + const chunks = []; + const stream = zlib.createBrotliCompress({ params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 5 } }); + console.log(stream instanceof zlib.BrotliCompress, stream instanceof zlib.Gzip); + stream.on("data", (chunk) => chunks.push(chunk)); + stream.on("end", () => { + console.log("stream", hex(Buffer.concat(chunks)), stream.bytesWritten); + const second = new zlib.BrotliCompress(); + const parts = []; + second.on("data", (chunk) => parts.push(chunk)); + second.on("end", () => { + console.log("class", hex(Buffer.concat(parts))); + try { zlib.createBrotliCompress({ params: { 99: 1 } }); } catch (e) { console.log(e.code, e.message); } + try { zlib.createBrotliCompress({ flush: 9 }); } catch (e) { console.log(e.code, e.message); } + }); + second.reset(); + second.end("reset first"); + }); + stream.write(text.subarray(0, 100)); + stream.flush(() => { + console.log("flushed", chunks.length > 0); + stream.end(text.subarray(100)); + }); +} diff --git a/tests/corpus/7715-zlib-brotli-decompress.cjs b/tests/corpus/7715-zlib-brotli-decompress.cjs new file mode 100644 index 000000000..c2f826f75 --- /dev/null +++ b/tests/corpus/7715-zlib-brotli-decompress.cjs @@ -0,0 +1,96 @@ +// zlib's Brotli decompression: fixed blobs Node produced, Brotli's own +// error codes (ERR_ + the decoder's error name) and zlib's for truncated +// input, trailing data, maxOutputLength, dictionaries, the decoder +// parameters, and the callback, promisified and stream forms. +const zlib = require("node:zlib"); +const { promisify } = require("node:util"); +const { pipeline, Readable, Writable } = require("node:stream"); + +const hello = Buffer.from("1b1600f88d946ede44558696206c6f350b32b54006543b", "hex"); +const repeated = Buffer.from("1b8713f825f0e2b14020680100", "hex"); +const withDictionary = Buffer.from("1b0a00f8250002980820", "hex"); +const tryIt = (label, run) => { + try { + const r = run(); + console.log(label, "ok", Buffer.isBuffer(r) ? r.length + " " + r.toString().slice(0, 24) : r); + } catch (e) { + console.log(label, e.name, e.code, e.errno, e.message); + } +}; + +tryIt("hello", () => zlib.brotliDecompressSync(hello)); +tryIt("repeated", () => zlib.brotliDecompressSync(repeated)); +tryIt("string input", () => zlib.brotliDecompressSync("abc")); +tryIt("arraybuffer input", () => zlib.brotliDecompressSync(hello.buffer.slice(hello.byteOffset, hello.byteOffset + hello.length))); +for (const hex of ["ff", "ffffffff", "ce", "0b008061", "3b00", "06", "2f", "1bffff00ffffffffffff"]) { + tryIt(hex, () => zlib.brotliDecompressSync(Buffer.from(hex, "hex"))); +} +tryIt("truncated", () => zlib.brotliDecompressSync(hello.subarray(0, 10))); +tryIt("trailing data", () => zlib.brotliDecompressSync(Buffer.concat([hello, Buffer.from("junk")]))); +tryIt("trailing data rejected", () => zlib.brotliDecompressSync(Buffer.concat([hello, Buffer.from("junk")]), { rejectGarbageAfterEnd: true })); +tryIt("maxOutputLength", () => zlib.brotliDecompressSync(repeated, { maxOutputLength: 100 })); +tryIt("small chunks", () => zlib.brotliDecompressSync(repeated, { chunkSize: 64 })); +tryIt("partial with flush", () => zlib.brotliDecompressSync(hello.subarray(0, 8), { finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH })); +tryIt("dictionary", () => zlib.brotliDecompressSync(withDictionary, { dictionary: Buffer.from("hello world") })); +tryIt("missing dictionary", () => zlib.brotliDecompressSync(withDictionary)); +tryIt("large window", () => zlib.brotliDecompressSync(hello, { params: { [zlib.constants.BROTLI_DECODER_PARAM_LARGE_WINDOW]: 1 } })); +tryIt("encoder param", () => zlib.brotliDecompressSync(hello, { params: { [zlib.constants.BROTLI_PARAM_LGWIN]: 10 } })); +tryIt("round trip", () => zlib.brotliDecompressSync(zlib.brotliCompressSync("round trip ".repeat(100))).toString() === "round trip ".repeat(100)); + +zlib.brotliDecompress(hello, (err, out) => { + console.log("callback", err, out.toString()); + zlib.brotliDecompress(Buffer.from([1, 2, 3]), (err2) => { + console.log("callback error", err2.code, err2.errno, err2.message); + promised(); + }); +}); + +function promised() { + const decompress = promisify(zlib.brotliDecompress); + decompress(repeated, { maxOutputLength: 10 }).catch((err) => { + console.log("promisified", err.code, err.message); + streams(); + }); +} + +function streams() { + const out = []; + const stream = zlib.createBrotliDecompress(); + console.log(stream instanceof zlib.BrotliDecompress, stream instanceof zlib.BrotliCompress); + stream.on("data", (chunk) => out.push(chunk)); + stream.on("end", () => { + console.log("stream", Buffer.concat(out).toString(), stream.bytesWritten); + const bad = new zlib.BrotliDecompress(); + bad.on("error", (err) => { + console.log("stream error", err.code, err.errno, err.message); + piped(); + }); + bad.write(Buffer.from("ffff", "hex")); + bad.end(); + }); + stream.write(hello.subarray(0, 5)); + stream.end(hello.subarray(5)); +} + +function piped() { + const sink = []; + pipeline( + Readable.from([Buffer.from("one "), Buffer.from("two "), Buffer.from("three")]), + zlib.createBrotliCompress(), + zlib.createBrotliDecompress(), + new Writable({ + write(chunk, _encoding, callback) { + sink.push(chunk); + callback(); + }, + }), + (err) => { + console.log("pipeline", err, Buffer.concat(sink).toString()); + try { + new zlib.BrotliDecompress({ params: { 3: 1 } }); + } catch (e) { + console.log(e.code, e.message); + } + }, + ); +} diff --git a/tests/corpus/7716-zlib-brotli.ts b/tests/corpus/7716-zlib-brotli.ts new file mode 100644 index 000000000..812cf6fae --- /dev/null +++ b/tests/corpus/7716-zlib-brotli.ts @@ -0,0 +1,47 @@ +// zlib's Brotli forms through their TypeScript types: typed options, +// dictionaries, maxOutputLength, the callback and promisified forms, and the +// BrotliCompress and BrotliDecompress classes. +import * as zlib from "node:zlib"; +import { promisify } from "node:util"; + +const input: string = "typed brotli ".repeat(64); +const compressed: Buffer = zlib.brotliCompressSync(input, { + params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 4, [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT }, +}); +console.log(compressed.toString("base64")); +console.log(zlib.brotliDecompressSync(compressed).toString() === input); +const dict: Buffer = Buffer.from("typed brotli"); +const withDict = zlib.brotliCompressSync(input, { dictionary: dict }); +console.log(withDict.length, zlib.brotliDecompressSync(withDict, { dictionary: dict }).length); +try { + zlib.brotliDecompressSync(compressed, { maxOutputLength: 16 }); +} catch (e) { + const err = e as NodeJS.ErrnoException; + console.log(err.code, err.message); +} +zlib.brotliCompress(Buffer.from("abc"), (err, out) => { + console.log(err, out.toString("hex")); + zlib.brotliDecompress(out, { finishFlush: zlib.constants.BROTLI_OPERATION_FINISH }, (err2, back) => { + console.log(err2, back.toString()); + main(); + }); +}); +const compressAsync = promisify(zlib.brotliCompress); +const decompressAsync = promisify(zlib.brotliDecompress); +async function main(): Promise { + const packed = await compressAsync("promised"); + console.log((await decompressAsync(packed)).toString()); + try { + await decompressAsync(Buffer.from([0xff])); + } catch (e) { + console.log((e as NodeJS.ErrnoException).code); + } + const stream: zlib.BrotliCompress = new zlib.BrotliCompress(); + const parts: Buffer[] = []; + stream.on("data", (c: Buffer) => parts.push(c)); + stream.on("end", () => console.log("stream", Buffer.concat(parts).equals(zlib.brotliCompressSync("streamed")), stream.bytesWritten)); + stream.end("streamed"); + const dec = zlib.createBrotliDecompress(); + dec.reset(); + console.log(dec instanceof zlib.BrotliDecompress); +} diff --git a/tests/corpus/7745-typed-array-unions.ts b/tests/corpus/7745-typed-array-unions.ts new file mode 100644 index 000000000..a7fc6f2cb --- /dev/null +++ b/tests/corpus/7745-typed-array-unions.ts @@ -0,0 +1,93 @@ +// Unions of typed-array classes: every element operation runs on each arm. + +type UintArray = Uint8Array | Uint16Array | Uint32Array; +type Samples = Int16Array | Float32Array | Float64Array; + +function uintArray(max: number, size: number): UintArray { + return max <= 2 ** 8 + ? new Uint8Array(size) + : max <= 2 ** 16 + ? new Uint16Array(size) + : new Uint32Array(size); +} + +function samples(kind: number, size: number): Samples { + return kind === 0 + ? new Int16Array(size) + : kind === 1 + ? new Float32Array(size) + : new Float64Array(size); +} + +function sum(xs: UintArray): number { + let total = 0; + for (let i = 0; i < xs.length; i++) total += xs[i]!; + return total; +} + +function describe(xs: UintArray): string { + if (xs instanceof Uint8Array) return `u8 ${xs.length}`; + if (xs instanceof Uint16Array) return `u16 ${xs[0]}`; + return `u32 ${xs.BYTES_PER_ELEMENT}`; +} + +for (const max of [200, 60000, 5000000]) { + const xs = uintArray(max, 6); + // Stores convert to each arm's element kind (wrapping past its range). + for (let i = 0; i < xs.length; i++) xs[i] = i * 70000 + 255; + console.log(xs.length, xs.byteLength, xs.byteOffset, xs.BYTES_PER_ELEMENT); + console.log(xs[0], xs[5], xs[6], xs[-1], sum(xs)); + xs[1] += 3; + xs[2]++; + --xs[3]; + xs[4] = -1; + xs[5] = 2.75; + console.log(xs[1], xs[2], xs[3], xs[4], xs[5]); + // Writes past the end are ignored, and reads there are undefined. + xs[10] = 9; + console.log(xs[10] === undefined, xs[10] ?? "missing"); + let iterated = 0; + for (const v of xs) iterated += v; + console.log(iterated, [...xs].length, Array.from(xs)[1]); + const part = xs.subarray(1, 4); + part[0] = 42; + console.log(part.length, xs[1], xs.slice(2, 4).length, xs.slice(2, 4)[0] === xs[2]); + xs.fill(7, 4); + xs.copyWithin(0, 4, 5); + console.log(xs.join("-"), xs.toReversed()[0]); + xs.set([1, 2], 2); + console.log(xs[2], xs[3], describe(xs)); +} + +for (const kind of [0, 1, 2]) { + const s = samples(kind, 4); + s[0] = 1.5; + s[1] = -40000; + s[2] = 0.1; + s[3] = s[0]! * 3; + console.log(s.BYTES_PER_ELEMENT, s[0], s[1], s[2], s[3]); + console.log(s); + console.log(s instanceof Float32Array, s instanceof Int16Array); +} + +// A stored value that reassigns the receiver or index stores into the +// receiver and at the index evaluated before it. +type Wide = Uint8Array | Uint16Array; +function rebound(wide: boolean): void { + const before: Wide = wide ? new Uint16Array(4) : new Uint8Array(4); + let u: Wide = before; + let i = 0; + const swap = (): number => { + u = new Uint16Array(4); + i = 2; + return 300; + }; + u[i] = swap(); + console.log(before, u, i); + const target = u; + target[1] = 5; + u[i] += swap(); + console.log(target, u, i); +} +rebound(false); +rebound(true); diff --git a/tests/corpus/7747-typed-array-class-values.ts b/tests/corpus/7747-typed-array-class-values.ts new file mode 100644 index 000000000..523896c96 --- /dev/null +++ b/tests/corpus/7747-typed-array-class-values.ts @@ -0,0 +1,42 @@ +// Typed-array unions chosen through class values, and held in fields, +// parameters, returns and records. + +type UintArray = Uint8Array | Uint16Array | Uint32Array; + +const pick = (max: number): { new (n: number): UintArray } => + max <= 2 ** 8 ? Uint8Array : max <= 2 ** 16 ? Uint16Array : Uint32Array; + +class Stack { + heap: UintArray; + length = 0; + constructor(max: number) { + const Heap = pick(max); + this.heap = new Heap(max); + } + push(n: number): void { + this.heap[this.length++] = n; + } + pop(): number | undefined { + return this.heap[--this.length]; + } +} + +for (const max of [10, 1000, 100000]) { + const stack = new Stack(max); + for (let i = 1; i <= 4; i++) stack.push(i * 250); + console.log(stack.heap.BYTES_PER_ELEMENT, stack.pop(), stack.pop(), stack.length); +} + +function grow(xs: UintArray, by: number): UintArray { + const Next = pick(xs.length * by); + const out = new Next(xs.length * by); + out.set(xs); + return out; +} + +const record: { data: UintArray; label: string } = { data: new Uint8Array([1, 2, 3]), label: "r" }; +record.data = grow(record.data, 100); +record.data[299] = 65535; +console.log(record.label, record.data.length, record.data[0], record.data[2], record.data[299]); +record.data = grow(record.data, 1000); +console.log(record.data.BYTES_PER_ELEMENT, record.data.length, record.data[1]); diff --git a/tests/corpus/7748-typed-array-number-array-unions.ts b/tests/corpus/7748-typed-array-number-array-unions.ts new file mode 100644 index 000000000..706ed37b5 --- /dev/null +++ b/tests/corpus/7748-typed-array-number-array-unions.ts @@ -0,0 +1,78 @@ +// Unions of typed arrays and number arrays, as a cache picks its index +// arrays by capacity: a linked list over next/prev index arrays. + +type NumberArray = Uint8Array | Uint16Array | Uint32Array | number[]; + +function indexArray(max: number): NumberArray { + if (max <= 2 ** 8) return new Uint8Array(max); + if (max <= 2 ** 16) return new Uint16Array(max); + if (max <= 2 ** 32) return new Uint32Array(max); + return new Array(4).fill(0); +} + +class Order { + next: NumberArray; + prev: NumberArray; + head = 0; + tail = 0; + size = 0; + + constructor(max: number, force = false) { + this.next = force ? new Array(max).fill(0) : indexArray(max); + this.prev = force ? new Array(max).fill(0) : indexArray(max); + } + + push(index: number): void { + if (this.size === 0) { + this.head = this.tail = index; + } else { + this.next[this.tail] = index; + this.prev[index] = this.tail; + this.tail = index; + } + this.size++; + } + + moveToTail(index: number): void { + if (index === this.tail) return; + if (index === this.head) this.head = this.next[index]!; + else this.next[this.prev[index]!] = this.next[index]!; + this.prev[this.next[index]!] = this.prev[index]!; + this.next[this.tail] = index; + this.prev[index] = this.tail; + this.tail = index; + } + + walk(): number[] { + const out: number[] = []; + for (let i = this.head, n = 0; n < this.size; n++, i = this.next[i]!) out.push(i); + return out; + } +} + +for (const [max, force] of [ + [8, false], + [300, false], + [70000, false], + [8, true], +] as const) { + const order = new Order(max, force); + for (let i = 0; i < 6; i++) order.push(i); + order.moveToTail(0); + order.moveToTail(3); + order.moveToTail(5); + console.log(max, force, order.walk().join(","), order.next.length, order.prev[3]); +} + +// The number-array arm reads holes and missing indexes as undefined, +// and writes past its length grow it. +const arms: NumberArray[] = [new Uint8Array(3), [1, 2, 3]]; +for (const a of arms) { + a[1] = 300; + a[2] += 0.5; + a[5] = 8; + console.log(a.length, a[1], a[2], a[4], a[5]); + let total = 0; + for (const v of a) total += v ?? -1; + console.log(total, [...a].length, Array.from(a).length); +} diff --git a/tests/corpus/7749-typed-array-element-searches.ts b/tests/corpus/7749-typed-array-element-searches.ts new file mode 100644 index 000000000..7cae267ec --- /dev/null +++ b/tests/corpus/7749-typed-array-element-searches.ts @@ -0,0 +1,22 @@ +// TypedArray indexOf, lastIndexOf and includes on every element kind, on +// Buffers (their own search), and on unions of typed arrays: strict +// equality for indexOf/lastIndexOf, SameValueZero for includes. +const f = new Float64Array([1, NaN, -0, 0, 2.5, NaN, 1]); +console.log(f.indexOf(NaN), f.includes(NaN), f.lastIndexOf(NaN)); +console.log(f.indexOf(0), f.indexOf(-0), f.lastIndexOf(0), f.lastIndexOf(-0), f.includes(-0)); +console.log(f.indexOf(1, 1), f.indexOf(1, -1), f.indexOf(1, -100), f.indexOf(1, 100), f.indexOf(1, 1.9)); +console.log(f.lastIndexOf(1, 5), f.lastIndexOf(1, -2), f.lastIndexOf(1, -100), f.lastIndexOf(1, 100), f.lastIndexOf(1, undefined)); +console.log(f.includes(2.5, 4), f.includes(2.5, 5), f.includes(2.5, -3), f.includes(NaN, 6)); +const u = new Uint8Array([0, 255, 3, 255]); +console.log(u.indexOf(255), u.indexOf(-1), u.indexOf(511), u.indexOf(3.5), u.includes(NaN), u.lastIndexOf(255)); +const i = new Int16Array([-5, 7, -5]); +console.log(i.indexOf(-5), i.lastIndexOf(-5), i.includes(7), i.indexOf(65531)); +const h = new Float32Array([0.1, 0.5, 16777217]); +console.log(h.indexOf(0.1), h.indexOf(0.5), h.includes(16777216), h.indexOf(16777217)); +const c = new Uint8ClampedArray([300, -4]); +console.log(c.indexOf(255), c.indexOf(0), new Uint32Array(0).indexOf(0), new Uint32Array(0).includes(0)); +const b = Buffer.from([1, 2, 3, 2]); +console.log(b.indexOf(2), b.indexOf(258), b.lastIndexOf(2), b.includes("\u0003")); +type UintArray = Uint8Array | Uint16Array | Uint32Array; +const mk = (n: number): UintArray => (n > 1 ? new Uint16Array([1, 700, 1]) : new Uint8Array([1, 188, 1])); +for (const x of [mk(1), mk(2)]) console.log(x.indexOf(700), x.lastIndexOf(1), x.includes(188), x.indexOf(1, 1)); diff --git a/tests/corpus/7750-typed-array-union-inspect.ts b/tests/corpus/7750-typed-array-union-inspect.ts new file mode 100644 index 000000000..aebb0dbdf --- /dev/null +++ b/tests/corpus/7750-typed-array-union-inspect.ts @@ -0,0 +1,14 @@ +// Printing u8 byte views whose static type does not say what they are: +// union arms, elements and fields print as Node does by the value's kind. +type UintArray = Uint8Array | Uint16Array | Uint32Array; +const mk = (n: number): UintArray => (n > 1 ? new Uint16Array([1, 700]) : new Uint8Array([1, 188])); +const a = mk(1), b = mk(2); +console.log(a, b); +console.log([a, b]); +const bufArm: Uint8Array | Uint16Array = Buffer.from([1, 2, 3]); +console.log(bufArm); +const u8s: Uint8Array[] = [new Uint8Array([9]), Buffer.from([10, 11])]; +console.log(u8s); +const rec: { bytes: Uint8Array; view: DataView } = { bytes: new Uint8Array(2), view: new DataView(new ArrayBuffer(2)) }; +console.log(rec); +console.log(new Uint8Array([5, 6]), Buffer.from([7])); diff --git a/tests/corpus/7752-typed-array-dynamic-methods.js b/tests/corpus/7752-typed-array-dynamic-methods.js new file mode 100644 index 000000000..a728e3ce9 --- /dev/null +++ b/tests/corpus/7752-typed-array-dynamic-methods.js @@ -0,0 +1,125 @@ +// %TypedArray%.prototype methods called on typed arrays held as untyped +// values, as JavaScript sources and Test262's testTypedArray.js use them. +const kinds = [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + +function show(label, value) { + console.log(label, value); +} + +// TA arrives untyped, as Test262's testWithTypedArrayConstructors passes it. +function check(TA) { + const a = new TA([3, 1, 2, 1, 0]); + show(TA.name + " search", [a.indexOf(1), a.lastIndexOf(1), a.includes(2), a.indexOf(1, 2), a.lastIndexOf(1, -3), a.includes(3, 1), a.indexOf(9), a.indexOf("1")]); + show(" map", a.map((v, i) => v * 2 + i)); + show(" filter", a.filter((v) => v > 0)); + show(" some/every", [a.some((v) => v > 2), a.every((v) => v >= 0), a.every((v) => v > 0)]); + show(" find", [a.find((v) => v < 2), a.findIndex((v) => v < 2), a.findLast((v) => v < 2), a.findLastIndex((v) => v < 2), a.find((v) => v > 5), a.findLastIndex((v) => v > 5)]); + show(" reduce", [a.reduce((s, v) => s + v), a.reduceRight((s, v, i) => s + "" + v + i, ""), a.reduce((s, v) => s * 10 + v, 0)]); + const seen = []; + a.forEach(function (v, i, arr) { seen.push([v, i, arr === a, this.tag]); }, { tag: "t" }); + show(" forEach", seen.map((x) => x.join(":")).join(" ")); + show(" sorted", [a.toSorted().join(), a.toSorted((x, y) => y - x).join(), a.toReversed().join(), a.with(1, 7).join(), a.with(-1, 9).join(), a.join()]); + show(" iterators", [[...a.keys()].join(), [...a.values()].join(), [...a.entries()].map((e) => e.join("=")).join(" ")]); + const b = a.slice(); + b.sort(); + show(" sort", [b.join(), b.reverse().join(), b.sort((x, y) => x - y) === b]); +} +kinds.forEach(check); + +// Edge cases over untyped constructors. +function edges(F, C, I, U, S) { + const f = new F([NaN, -0, 0, 1, -Infinity, NaN]); + show("float search", [f.indexOf(NaN), f.includes(NaN), f.indexOf(-0), f.lastIndexOf(0), f.includes(-0)]); + show("float sort", Array.from(f.toSorted(), (v) => Object.is(v, -0) ? "-0" : String(v)).join()); + show("clamped map", new C([1, 2]).map((v) => v * 200)); + show("wrapping map", new I([1, 2]).map((v) => v * 100)); + const live = new U([1, 2, 3]); + show("live", live.map((v, i, arr) => { if (i === 0) arr[2] = 9; return v; })); + for (const bad of [() => new I(2).forEach(1), () => new I(0).reduce((a, b) => a), () => new I(2).with(5, 1), () => new I(2).sort("x")]) { + try { + bad(); + show("no throw", ""); + } catch (e) { + show(e.constructor.name, e.message.length > 0); + } + } + let order = []; + new S([5, 1, 4]).sort((x, y) => { order.push(x + "" + y); return x - y; }); + show("comparator calls", order.length > 0); +} +edges(Float64Array, Uint8ClampedArray, Int8Array, Uint8Array, Int16Array); + +// Method values, and the constructors' from and of. +function run(TA) { + const s = new TA([1, 2, 3]); + console.log(typeof s.findLast, typeof s.with, typeof s.toSorted, typeof s.map, typeof s.at); + const m = s.findLast; + console.log(m.call(s, (v) => v < 3)); + console.log(typeof TA.from, typeof TA.of); +} +run(Int16Array); +function statics(TA) { + console.log(TA.from([1, 2, 300]), TA.from({ length: 2, 0: "7", 1: 8 }), TA.from(new Set([4, 5]), (v, k) => v * 10 + k)); + console.log(TA.of(1, 2, 3), TA.of(), TA.from({ [Symbol.iterator]: function* () { yield 9; yield 8; } })); + try { TA.from([1], 5); } catch (e) { console.log(e.constructor.name); } + try { TA.from(null); } catch (e) { console.log(e.constructor.name); } +} +statics(Uint8Array); +statics(Float32Array); + +// TypedArray.from and TypedArray.of with other constructors as this. +function customs(TA) { + let calls = []; + function Big(n) { calls.push(n); return new TA(n + 2); } + const fromBig = TA.from.call(Big, [1, 2, 3], (v) => v * 2); + console.log(fromBig, calls); + console.log(TA.of.call(Big, 7, 8)); + function attempt(label, C) { + try { TA.from.call(C, [1, 2]); console.log(label, "no throw"); } catch (e) { console.log(label, e.constructor.name); } + try { TA.of.call(C, 1, 2); console.log(label, "no throw"); } catch (e) { console.log(label, e.constructor.name); } + } + attempt("small", function () { return new TA(1); }); + attempt("plain", function () { return {}; }); + attempt("arrow", () => new TA(5)); + attempt("number", 5); + const order = []; + const arrayLike = { length: 2, get 0() { order.push("get0"); return 1; }, get 1() { order.push("get1"); return 2; } }; + TA.from.call(function (n) { order.push("create" + n); return new TA(n); }, arrayLike, (v) => { order.push("map" + v); return v; }); + console.log(order.join(" ")); +} +customs(Int32Array); + +// Reducers and comparators run with an undefined this, also through method +// values; a Symbol.iterator getter is read once. +function review(TA) { + "use strict"; + const ta = new TA([3, 1, 2]); + const seen = []; + const reduce = ta.reduce, reduceRight = ta.reduceRight, sort = ta.sort, toSorted = ta.toSorted; + reduce.call(ta, function (a, b) { seen.push(this === undefined); return a + b; }); + reduceRight.call(ta, function (a, b) { seen.push(this === undefined); return a + b; }, 0); + sort.call(ta.slice(), function (x, y) { seen.push(this === undefined); return x - y; }); + toSorted.call(ta, function (x, y) { seen.push(this === undefined); return y - x; }); + console.log(seen.every((v) => v), seen.length > 0); + let gets = 0; + const source = {}; + Object.defineProperty(source, Symbol.iterator, { get() { gets++; return function* () { yield 4; yield 5; }; } }); + console.log(new TA(source), gets); + console.log(TA.from(source), gets); +} +review(Uint8Array); +function plainIterator(TA) { + let gets = 0, nexts = 0; + const source = {}; + Object.defineProperty(source, Symbol.iterator, { + get() { + gets++; + return function () { + let i = 0; + return { next() { nexts++; return i < 2 ? { value: 10 + i++, done: false } : { value: undefined, done: true }; } }; + }; + }, + }); + console.log(new TA(source), TA.from(source, (v) => v * 2), gets, nexts); +} +plainIterator(Int16Array); diff --git a/tests/corpus/7796-boxed-subclass-identity.js b/tests/corpus/7796-boxed-subclass-identity.js new file mode 100644 index 000000000..12ed8b3c5 --- /dev/null +++ b/tests/corpus/7796-boxed-subclass-identity.js @@ -0,0 +1,106 @@ +"use strict"; +// Class instances of a hierarchy cross into untyped code through their +// base type many times. Each crossing names the same object: identity, +// Map, Set and WeakMap keys, properties added through untyped code, and +// field writes from either side stay one object, and every subclass keeps +// its own members, as in Node. + +class Shape { + constructor(name) { + this.name = name; + this.hits = 0; + } + area() { + return 0; + } + describe() { + return `${this.name}:${this.area()}`; + } +} + +class Square extends Shape { + constructor(side) { + super("square"); + this.side = side; + } + area() { + return this.side * this.side; + } +} + +class Cube extends Square { + constructor(side) { + super(side); + this.name = "cube"; + } + area() { + return 6 * super.area(); + } + get volume() { + return this.side ** 3; + } +} + +class Circle extends Shape { + constructor(r) { + super("circle"); + this.r = r; + } + area() { + return Math.round(Math.PI * this.r * this.r); + } +} + +/** @param {any} value */ +function untyped(value) { + return value; +} +/** @param {any} value @param {string} key @param {unknown} extra */ +function tag(value, key, extra) { + value[key] = extra; + value.hits++; + return value; +} + +/** @param {Shape} shape */ +function crossAsBase(shape) { + return untyped(shape); +} + +const shapes = [new Shape("plain"), new Square(2), new Cube(3), new Circle(1)]; +const seen = new Map(); +const weak = new WeakMap(); +const set = new Set(); +for (let round = 0; round < 50; round++) { + for (const shape of shapes) { + const boxed = crossAsBase(shape); + if (round === 0) { + seen.set(boxed, shape.name); + weak.set(boxed, round); + } + set.add(boxed); + if (boxed !== shape || untyped(boxed) !== crossAsBase(shape)) console.log("identity lost", shape.name); + } +} +console.log(seen.size, set.size, shapes.map((s) => seen.get(crossAsBase(s))).join(","), shapes.every((s) => weak.has(untyped(s)))); + +for (const shape of shapes) { + const boxed = crossAsBase(shape); + tag(boxed, "color", shape.name.length); + shape.hits += 10; + console.log(boxed.describe(), boxed.area(), boxed.hits, shape.hits, boxed.color, Object.keys(boxed).join(",")); + console.log(boxed instanceof Shape, boxed instanceof Square, boxed instanceof Cube, boxed instanceof Circle, boxed.constructor.name); +} + +/** @type {Shape} */ +const asBase = shapes[2]; +const cube = crossAsBase(asBase); +console.log(cube.volume, JSON.stringify(cube), "side" in cube, "volume" in cube, Object.prototype.hasOwnProperty.call(cube, "volume")); +/** @type {any} */ (shapes[1]).side = 5; +console.log(crossAsBase(shapes[1]).area(), shapes[1].area(), untyped(shapes[1]).side); + +const many = []; +for (let i = 0; i < 1000; i++) many.push(crossAsBase(i % 2 ? new Square(i) : new Circle(i))); +let squares = 0; +for (const item of many) if (item instanceof Square) squares += item.side; +console.log(many.length, squares, many[999].describe(), many[998].describe()); diff --git a/tests/corpus/7982-integer-view-compares.ts b/tests/corpus/7982-integer-view-compares.ts new file mode 100644 index 000000000..5978eaf86 --- /dev/null +++ b/tests/corpus/7982-integer-view-compares.ts @@ -0,0 +1,85 @@ +// Loops whose integer locals take part in compares and typed-array indexes as +// `i + 1`, `i - 1` and `2 * i + 1`: heap sift-downs, neighbor reads at both +// ends of an array, a binary search, and counters near 2^53, where the sum +// of a counter and a constant is still an exact double. + +function siftDown(a: Int32Array, start: number, end: number): void { + let root = start; + while (2 * root + 1 < end) { + let child = 2 * root + 1; + if (child + 1 < end && a[child]! < a[child + 1]!) child++; + if (a[root]! >= a[child]!) return; + const t = a[root]!; + a[root] = a[child]!; + a[child] = t; + root = child; + } +} + +function heapSort(a: Int32Array): string { + for (let start = (a.length >> 1) - 1; start >= 0; start--) siftDown(a, start, a.length); + for (let end = a.length - 1; end > 0; end--) { + const t = a[0]!; + a[0] = a[end]!; + a[end] = t; + siftDown(a, 0, end); + } + return Array.from(a).join(); +} + +function neighbors(a: Float64Array): string { + const out: number[] = []; + let i = 0; + while (i < a.length) { + out.push(a[i - 1]! + a[i + 1]!); + i = i + 1; + } + return out.join(); +} + +function lowerBound(a: Int32Array, value: number): number { + let lo = 0; + let hi = a.length; + while (lo < hi) { + const mid = lo + ((hi - lo) >> 1); + if (a[mid]! < value) lo = mid + 1; + else hi = mid; + } + return lo; +} + +function nearLimit(start: number): string { + const seen: string[] = []; + let i = start; + let n = 0; + while (n < 4) { + seen.push(`${i + 1 > 9007199254740991}:${i + 1 === i + 2}:${i - 1 < i}`); + i = i + 1; + n = n + 1; + } + return seen.join(" "); +} + +function atLimit(start: number, end: number): string { + // A counter of integer locals only, up to 2^53 - 1: `i + 2` may be + // 2^53 + 1, whose double is 2^53, so `i + 1 === i + 2` holds at the end. + let same = 0; + let above = 0; + let mixed = 0; + for (let i = start; i <= end; i++) { + if (i + 1 === i + 2) same++; + if (i + 2 > 9007199254740992) above++; + mixed += (i * 2) % 3; + } + return `${same} ${above} ${mixed}`; +} + +console.log(heapSort(new Int32Array([5, -3, 9, 0, 9, 2147483647, -2147483648, 7, 1]))); +console.log(heapSort(new Int32Array([])), heapSort(new Int32Array([4]))); +console.log(neighbors(new Float64Array([1, 2, 3, 4]))); +const sorted = new Int32Array([-5, -1, 0, 0, 3, 8, 8, 13]); +console.log([-6, -1, 0, 1, 8, 13, 14].map((v) => lowerBound(sorted, v)).join()); +console.log(nearLimit(9007199254740988)); +console.log(nearLimit(-9007199254740991)); +console.log(atLimit(9007199254740988, 9007199254740991)); +console.log(atLimit(-9007199254740991, -9007199254740988)); diff --git a/tests/corpus/7991-unknown-class-union-casts.ts b/tests/corpus/7991-unknown-class-union-casts.ts new file mode 100644 index 000000000..6560abbc2 --- /dev/null +++ b/tests/corpus/7991-unknown-class-union-casts.ts @@ -0,0 +1,70 @@ +// Checked casts from `unknown` to unions of classes: each instance selects +// its own arm, whatever the order of the arms, including subclasses, arrays +// of instances, instances inside records, and values of no listed class. +class Circle { + readonly r: number; + constructor(r: number) { + this.r = r; + } + area(): number { + return Math.round(Math.PI * this.r * this.r); + } +} +class Square { + readonly side: number; + constructor(side: number) { + this.side = side; + } + area(): number { + return this.side * this.side; + } +} +class Rect { + readonly w: number; + readonly h: number; + constructor(w: number, h: number) { + this.w = w; + this.h = h; + } + area(): number { + return this.w * this.h; + } +} +class Tile extends Square { + label(): string { + return `tile ${this.side}`; + } +} + +type Shape = Circle | Square | Rect; + +function describe(value: unknown): string { + try { + const shape = value as Shape; + const kind = shape instanceof Circle ? "circle" : shape instanceof Rect ? "rect" : "square"; + return `${kind} ${shape.area()}`; + } catch (error) { + return `rejected: ${(error as Error).name}`; + } +} + +const values: unknown[] = [new Circle(2), new Square(3), new Rect(2, 5), new Tile(4), { side: 3 }, 7, null]; +for (const value of values) console.log(describe(value)); + +const reversed = values.slice(0, 4).reverse() as Shape[]; +console.log(reversed.map((s) => s.area()).join(",")); + +const boxed: unknown = { first: new Rect(1, 2), second: new Circle(1) }; +const pair = boxed as { first: Shape; second: Shape }; +console.log(pair.first.area(), pair.second.area(), pair.first instanceof Rect); + +const tiles: unknown = [new Tile(1), new Tile(2)]; +const asSquares = tiles as Square[]; +console.log(asSquares.map((t) => t.area()).join(" "), asSquares[0] instanceof Tile); + +let total = 0; +for (let i = 0; i < 1000; i++) { + const v: unknown = i % 3 === 0 ? new Circle(1) : i % 3 === 1 ? new Square(2) : new Rect(1, 3); + total += (v as Shape).area(); +} +console.log(total); diff --git a/tests/corpus/8101-url-host-and-path-parsing.js b/tests/corpus/8101-url-host-and-path-parsing.js new file mode 100644 index 000000000..6b04dd9ef --- /dev/null +++ b/tests/corpus/8101-url-host-and-path-parsing.js @@ -0,0 +1,103 @@ +// WHATWG URL host and path parsing: special hosts are percent-decoded and +// checked for forbidden domain code points (and read as IPv4 when they end +// in a number), opaque hosts and paths percent-encode the C0 control set, +// file: URLs take no port or credentials, empty hosts refuse credentials and +// ports, and host-less paths that start with "//" round-trip. Cases from the +// WPT url test data. +const parses = [ + ["file://example:1/", null], + ["non-special:opaque ?hi", null], + ["non-special:opaque #hi", null], + ["non-special:opaque \t\t \t#hi", null], + ["non-special:opaque \t\t #hi", null], + ["non-special:opaque\t\t \r #hi", null], + ["sc://faß.ExAmPlE/", null], + ["http://%30%78%63%30%2e%30%32%35%30.01", "http://other.com/"], + ["http://%30%78%63%30%2e%30%32%35%30.01%2e", "http://other.com/"], + ["sc://ñ.test/", null], + ["sc://%/", null], + ["sc://@/", null], + ["sc://te@s:t@/", null], + ["sc://:/", null], + ["sc://:12/", null], + ["x", "sc://ñ"], + ["wow:\uFFFF", null], + ["http://a\u007Fb/", null], + ["sc://\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\u000b\f\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f\u007F!\"$%&'()*+,-.;=_`{}~/", null], + ["asdf://%43%7C/", null], + ["C|", "file://host/dir/file"], + ["C|", "file://host/D:/dir1/dir2/file"], + ["C|#", "file://host/dir/file"], + ["C|?", "file://host/dir/file"], + ["C|/", "file://host/dir/file"], + ["C|\n/", "file://host/dir/file"], + ["C|\\", "file://host/dir/file"], + ["C|/", "file://host/"], + ["file:C:/", "file://host/"], + ["sc://ñ", null], + ["sc://ñ?x", null], + ["sc://ñ#x", null], + ["#x", "sc://ñ"], + ["?x", "sc://ñ"], + ["", "non-spec:/..//p"], + ["path", "non-spec:/..//p"], + ["../path", "non-spec:/.//p"], + ["non-special://%E2%80%A0/", null], + ["non-special://H%4fSt/path", null], + ["non-special:cannot-be-a-base-url-\u0000\u0001\u001f\u001e~\u007F\u0080", null], + ["foo://!\"$%&'()*+,-.;=_`{}~/", null], + ["foo://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~", null], + ["wss://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~", null], + ["non-special:\u0000y", null], + ["non-special:x/\u0000y", null], + ["non-special:\uFFFFy", null], + ["non-special:x/\uFFFFy", null], + ["data://:443", null], + ["javascript://:443", null], + ["mailto://:443", null], + ["intent://:443", null], + ["urn://:443", null], + ["turn://:443", null], + ["stun://:443", null], +]; +function describe(url) { + return [url.href, url.protocol, url.username, url.password, url.host, url.hostname, url.port, url.pathname, url.search, url.hash].join(" | "); +} +for (const [input, base] of parses) { + let line; + try { + line = describe(base === null ? new URL(input) : new URL(input, base)); + } catch (e) { + line = `throws ${e.code}`; + } + console.log(JSON.stringify(input), JSON.stringify(base), "=>", line); +} + +const writes = [ + ["host", "sc://x/", "ß"], + ["host", "file://y/", "loc%41lhost"], + ["hostname", "file://y/", "loc%41lhost"], + ["pathname", "a:/", "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007F\u0080\u0081Éé"], + ["search", "data:space ?query", ""], + ["search", "sc:space ?query", ""], + ["search", "data:space ?query#fragment", ""], + ["search", "sc:space ?query#fragment", ""], + ["hash", "data:space #fragment", ""], + ["hash", "sc:space #fragment", ""], + ["hash", "data:space ?query#fragment", ""], + ["hash", "sc:space ?query#fragment", ""], +]; +for (const [name, href, value] of writes) { + const url = new URL(href); + if (name === "host") url.host = value; + else if (name === "hostname") url.hostname = value; + else if (name === "port") url.port = value; + else if (name === "pathname") url.pathname = value; + else if (name === "protocol") url.protocol = value; + else if (name === "username") url.username = value; + else if (name === "password") url.password = value; + else if (name === "search") url.search = value; + else if (name === "hash") url.hash = value; + else if (name === "href") url.href = value; + console.log(name, JSON.stringify(href), JSON.stringify(value), "=>", describe(url)); +} diff --git a/tests/corpus/8102-url-path-to-file-url-unc-hosts.js b/tests/corpus/8102-url-path-to-file-url-unc-hosts.js new file mode 100644 index 000000000..a96d1252e --- /dev/null +++ b/tests/corpus/8102-url-path-to-file-url-unc-hosts.js @@ -0,0 +1,36 @@ +// pathToFileURL(path, { windows: true }) parses a UNC servername with the URL +// host parser after dropping tabs and newlines and stopping at '#' and '?': +// forbidden host code points throw ERR_INVALID_URL, and the +// name is lowercased, percent-decoded and read as IPv4 when it ends in a +// number. "~" in a path is percent-encoded. +import url from "node:url"; +const paths = [ + "\\\\exa mple\\share\\file.txt", + "\\\\host name\\share\\file.txt", + "\\\\host@name\\share\\file.txt", + "\\\\host:name\\share\\file.txt", + "\\\\host[name\\share\\file.txt", + "\\\\host]name\\share\\file.txt", + "\\\\h Object.prototype.hasOwnProperty.call(object, key); + +const objectKeys = ["constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toString", "toLocaleString", "valueOf", "__proto__", "__defineGetter__", "__lookupSetter__", "missing", "length"]; +for (const key of objectKeys) console.log("Object.prototype", key, has(Object.prototype, key), Object.hasOwn(Object.prototype, key)); +console.log(Object.getOwnPropertyNames(Object.prototype).join(",")); +console.log(Object.prototype.hasOwnProperty("isPrototypeOf"), Object.prototype.hasOwnProperty("nope")); + +const arrayKeys = ["constructor", "push", "map", "length", "at", "hasOwnProperty", "isPrototypeOf", "missing"]; +for (const key of arrayKeys) console.log("Array.prototype", key, has(Array.prototype, key)); +const arrayNames = Object.getOwnPropertyNames(Array.prototype); +console.log(arrayNames.length, arrayNames.includes("constructor"), arrayNames.includes("length"), arrayNames.includes("hasOwnProperty")); + +/** @param {any} value */ +function links(label, value) { + const ctor = value.constructor; + const prototype = ctor.prototype; + console.log(label, typeof ctor, ctor.name, typeof prototype, prototype === Object.getPrototypeOf(value), has(prototype, "constructor"), has(prototype, "isPrototypeOf")); +} +links("object", {}); +links("object-with-keys", { a: 1, b: [2] }); +links("parsed", JSON.parse('{"x":{"y":1}}')); +links("nested", JSON.parse('{"x":{"y":1}}').x); +links("array", []); +links("array-of", [1, 2, 3]); +const error = new Error("boom"); +console.log("error", typeof error.constructor, error.constructor.name, error.constructor.prototype === Error.prototype, has(error.constructor.prototype, "isPrototypeOf")); + +/** @param {any} value */ +const ctorOf = (value) => value.constructor; +console.log(ctorOf({}) === Object, ctorOf({}).prototype === Object.prototype, ctorOf([]) === Array, ctorOf([]).prototype === Array.prototype); +console.log(Object.prototype.constructor === Object, Object.prototype.constructor.prototype === Object.prototype); +console.log(Object.getPrototypeOf({}) === Object.prototype, has(Object.getPrototypeOf({ k: 1 }), "isPrototypeOf")); + +const O = ctorOf({}); +const descriptor = Object.getOwnPropertyDescriptor(O, "prototype"); +console.log(typeof O.prototype, O.prototype === Object.prototype, descriptor.writable, descriptor.enumerable, descriptor.configurable); +const A = ctorOf([]); +console.log(A.prototype === Array.prototype, Object.keys(A).length, A.name, A.length); +const E = ctorOf(error); +console.log(E.prototype === Error.prototype, E.prototype.name, E.name); + +// A check shaped like zod's isPlainObject: the constructor's prototype must +// be an object that has its own isPrototypeOf. +/** @param {unknown} o */ +function isPlainObject(o) { + if (typeof o !== "object" || o === null || Array.isArray(o)) return false; + const ctor = /** @type {any} */ (o).constructor; + if (ctor === undefined) return true; + if (typeof ctor !== "function") return true; + const prot = ctor.prototype; + if (typeof prot !== "object" || prot === null || Array.isArray(prot)) return false; + return Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf"); +} +class Point { + constructor() { + this.x = 1; + } +} +const samples = [{}, { a: 1 }, JSON.parse("{}"), Object.create(null), [], new Point(), new Error("e"), { constructor: 5 }, { constructor: undefined }, "s", 1, null]; +console.log(samples.map((sample) => isPlainObject(sample)).join(",")); + +// A constructor stored on Array.prototype stays one own name, after length. +function Replacement() {} +Array.prototype.constructor = Replacement; +const replacedNames = Object.getOwnPropertyNames(Array.prototype); +console.log(replacedNames.slice(0, 2).join(","), replacedNames.filter((name) => name === "constructor").length, has(Array.prototype, "constructor")); diff --git a/tests/corpus/8111-plain-object-check-unknown.ts b/tests/corpus/8111-plain-object-check-unknown.ts new file mode 100644 index 000000000..267f3d65e --- /dev/null +++ b/tests/corpus/8111-plain-object-check-unknown.ts @@ -0,0 +1,54 @@ +// A plain-object check over unknown values, the way schema libraries +// accept records: the value's constructor must be absent, not a function, +// or one whose prototype has its own isPrototypeOf. Values that crossed +// JSON.parse and object literals pass; arrays, class instances and errors +// fail. + +function isObject(data: unknown): data is Record { + return typeof data === "object" && data !== null && !Array.isArray(data); +} + +function isPlainObject(o: unknown): o is Record { + if (!isObject(o)) return false; + const ctor: unknown = o.constructor; + if (ctor === undefined) return true; + if (typeof ctor !== "function") return true; + const prot: unknown = (ctor as { prototype?: unknown }).prototype; + if (!isObject(prot)) return false; + if (Object.prototype.hasOwnProperty.call(prot, "isPrototypeOf") === false) return false; + return true; +} + +class Point { + x = 1; +} + +const inputs: [string, unknown][] = [ + ["literal", { a: 1 }], + ["empty", {}], + ["parsed", JSON.parse('{"k":[1,2],"m":{"n":true}}')], + ["parsed-nested", (JSON.parse('{"m":{"n":true}}') as { m: unknown }).m], + ["null-proto", Object.create(null)], + ["array", [1, 2]], + ["instance", new Point()], + ["error", new Error("x")], + ["ctor-number", { constructor: 3 }], + ["string", "s"], + ["null", null], +]; + +for (const [label, value] of inputs) { + console.log(label, isPlainObject(value)); +} + +const records: Record = {}; +for (const [label, value] of inputs) { + if (!isPlainObject(value)) continue; + records[label] = Object.keys(value).length; +} +console.log(JSON.stringify(records)); + +const proto: unknown = Object.getPrototypeOf({}); +console.log(proto === Object.prototype, Object.prototype.hasOwnProperty.call(proto, "isPrototypeOf")); +console.log(Object.hasOwn(Object.prototype, "hasOwnProperty"), Object.hasOwn(Object.prototype, "nope")); +console.log(Object.getOwnPropertyNames(Object.prototype).length); diff --git a/tests/corpus/8112-error-factory-own-key-order.js b/tests/corpus/8112-error-factory-own-key-order.js new file mode 100644 index 000000000..3e7cf277a --- /dev/null +++ b/tests/corpus/8112-error-factory-own-key-order.js @@ -0,0 +1,73 @@ +"use strict"; +// Errors built by a constructor factory, the way zod 4 builds ZodError: a +// class extending the parent passed in, then an initializer that assigns +// `name`, defines non-enumerable fields and an enumerable `message` +// accessor, and a second initializer that reassigns `name`. JSON and +// Object.keys list `name` before `message`, as they were created, and +// `name` holds the last assignment. + +const messageDescriptor = { + get() { + return this.state.message ?? JSON.stringify(this.state.issues); + }, + set(value) { + this.state.message = value; + }, + enumerable: true, + configurable: true, +}; + +function factory(name, initializer, parent) { + const Parent = parent ?? Object; + class Definition extends Parent {} + Object.defineProperty(Definition, "name", { value: name }); + function construct(def) { + const instance = parent ? new Definition() : this; + Object.defineProperty(instance, "state", { value: { issues: def }, enumerable: false }); + initializer(instance, def); + return instance; + } + Object.defineProperty(construct, "init", { value: initializer }); + Object.defineProperty(construct, "name", { value: name }); + return construct; +} + +const baseInit = (instance, def) => { + instance.name = "$BaseError"; + Object.defineProperty(instance, "issues", { value: def, enumerable: false }); + Object.defineProperty(instance, "message", messageDescriptor); +}; +const BaseError = factory("$BaseError", baseInit, Error); +const ReportError = factory( + "ReportError", + (instance, def) => { + BaseError.init(instance, def); + instance.name = "ReportError"; + }, + Error, +); + +const report = new ReportError([{ code: "too_small", path: ["title"] }]); +console.log(report.name, report instanceof Error, Object.keys(report).join(",")); +console.log(JSON.stringify(report)); +console.log(JSON.stringify({ success: false, error: report })); +report.message = "replaced"; +console.log(JSON.stringify(report), report.message); +report.name = "Renamed"; +console.log(JSON.stringify(report), report.name); + +const base = new BaseError([1, 2]); +console.log(base.name, Object.keys(base).join(","), JSON.stringify(base)); + +// The same steps on a class extending Error directly. +function build(flag) { + class Direct extends Error {} + const instance = flag ? new Direct() : {}; + instance.name = "First"; + Object.defineProperty(instance, "message", messageDescriptor); + Object.defineProperty(instance, "state", { value: { issues: ["i"] }, enumerable: false }); + instance.name = "Second"; + return instance; +} +const direct = build(true); +console.log(Object.keys(direct).join(","), JSON.stringify(direct), direct.name); diff --git a/tests/corpus/8113-error-class-field-before-name.js b/tests/corpus/8113-error-class-field-before-name.js new file mode 100644 index 000000000..e10a9456b --- /dev/null +++ b/tests/corpus/8113-error-class-field-before-name.js @@ -0,0 +1,78 @@ +"use strict"; +// Error subclasses with a property bag that a later dynamic definition or +// write commits. Object.keys and JSON keep the order in which an instance +// created its properties: a class field before an own `name` that is +// assigned after construction, a `name` a constructor assigns before a +// later property, and a `message` that Error's constructor created before +// all of them. + +const messageDescriptor = { + get() { + return "described"; + }, + enumerable: true, + configurable: true, +}; + +// A factory-built class: the field, then an initializer that assigns `name` +// and defines `message`. +function factory(initializer) { + class Definition extends Error { + code = "E_FIELD"; + } + return function construct() { + const instance = new Definition(); + initializer(instance); + return instance; + }; +} +const Fielded = factory((instance) => { + instance.name = "Fielded"; + Object.defineProperty(instance, "message", messageDescriptor); +}); +const fielded = new Fielded(); +console.log(Object.keys(fielded).join(","), JSON.stringify(fielded)); +fielded.extra = 1; +console.log(Object.keys(fielded).join(","), JSON.stringify(fielded)); +fielded.name = "Renamed"; +console.log(Object.keys(fielded).join(","), JSON.stringify(fielded), fielded.name); + +// A class whose constructor passes a message to Error and then assigns +// `name`; the message is redefined after construction. +class Direct extends Error { + code = "E_DIRECT"; + constructor() { + super("constructed"); + this.name = "Direct"; + } +} +function redefine(instance) { + Object.defineProperty(instance, "message", messageDescriptor); + instance.extra = 2; + return instance; +} +const direct = redefine(new Direct()); +console.log(Object.keys(direct).join(","), JSON.stringify(direct), direct.name); + +// Constructors that assign `name` and then another property, which their +// instances create in that order, with and without a message passed to +// Error, before the message is redefined. +class Named extends Error { + constructor() { + super(); + this.name = "Named"; + this.detail = "named"; + } +} +const named = redefine(new Named()); +console.log(Object.keys(named).join(","), JSON.stringify(named), named.name); + +class NamedMessage extends Error { + constructor() { + super("constructed"); + this.name = "NamedMessage"; + this.detail = "named"; + } +} +const namedMessage = redefine(new NamedMessage()); +console.log(Object.keys(namedMessage).join(","), JSON.stringify(namedMessage), namedMessage.name); diff --git a/tests/corpus/8115-error-prototype-identity.js b/tests/corpus/8115-error-prototype-identity.js new file mode 100644 index 000000000..5c98e1209 --- /dev/null +++ b/tests/corpus/8115-error-prototype-identity.js @@ -0,0 +1,55 @@ +"use strict"; +// Object.getPrototypeOf of an Error is Error.prototype, whose own prototype +// is Object.prototype: with or without a message, after its name is +// reassigned, and when it was thrown and caught. + +const describe = (label, value) => { + const proto = Object.getPrototypeOf(value); + console.log(label, proto === Error.prototype, proto === Object.prototype, Object.getPrototypeOf(proto) === Object.prototype); +}; + +describe("message", new Error("boom")); +describe("empty", new Error()); +const renamed = new Error("x"); +renamed.name = "Custom"; +describe("renamed", renamed); +const coded = new Error("y"); +coded.code = "E_CODE"; +describe("coded", coded); +try { + throw new Error("thrown"); +} catch (error) { + describe("caught", error); +} + +// Walks up the chain, as error serializers and type sniffers do. +/** @param {unknown} value */ +function chainLength(value) { + let length = 0; + for (let current = Object.getPrototypeOf(value); current !== null; current = Object.getPrototypeOf(current)) length++; + return length; +} +console.log(chainLength(new Error("a")), chainLength({}), chainLength([])); + +/** @param {unknown} value */ +function kind(value) { + if (typeof value !== "object" || value === null) return typeof value; + const proto = Object.getPrototypeOf(value); + if (proto === Object.prototype || proto === null) return "plain"; + if (proto === Error.prototype) return "error"; + if (proto === Array.prototype) return "array"; + return "other"; +} +const values = [new Error("e"), {}, Object.create(null), [], JSON.parse('{"a":1}'), "s"]; +console.log(values.map(kind).join(",")); +const proto = Object.getPrototypeOf(new Error("m")); +console.log(proto.name, JSON.stringify(proto.message), Object.prototype.hasOwnProperty.call(proto, "name")); + +// After Object.setPrototypeOf, the prototype is the object that was set. +const custom = {}; +const moved = Object.setPrototypeOf(new Error("moved"), custom); +console.log(Object.getPrototypeOf(moved) === custom, Object.getPrototypeOf(moved) === Error.prototype); +const named = { kind: "named" }; +const movedNamed = new Error(); +Object.setPrototypeOf(movedNamed, named); +console.log(Object.getPrototypeOf(movedNamed) === named, Object.getPrototypeOf(movedNamed).kind); diff --git a/tests/corpus/8129-brotli-long-param-name.cjs b/tests/corpus/8129-brotli-long-param-name.cjs new file mode 100644 index 000000000..c3d1e1712 --- /dev/null +++ b/tests/corpus/8129-brotli-long-param-name.cjs @@ -0,0 +1,23 @@ +// A Brotli params key that names no parameter: ERR_BROTLI_INVALID_PARAM +// carries the whole key, however long, in Node's message. +const zlib = require("node:zlib"); +for (const key of ["k".repeat(5000), "é".repeat(300) + "x", "9", "-1", "1.5", "x"]) { + try { + zlib.brotliCompressSync("data", { params: { [key]: 1 } }); + console.log("accepted", key.length); + } catch (err) { + const suffix = " is not a valid Brotli parameter"; + console.log( + err.name, + err.code, + err.message.length, + err.message === key + suffix, + err.message.slice(-suffix.length - 3), + ); + } +} +try { + zlib.createBrotliDecompress({ params: { ["p".repeat(100000)]: 0 } }); +} catch (err) { + console.log(err.name, err.code, err.message.length, err.message.startsWith("pppp")); +} diff --git a/tests/corpus/8160-assert-expected-from-fields.cjs b/tests/corpus/8160-assert-expected-from-fields.cjs new file mode 100644 index 000000000..4c16bd78f --- /dev/null +++ b/tests/corpus/8160-assert-expected-from-fields.cjs @@ -0,0 +1,58 @@ +// Expected errors stored in an object literal's fields: a JavaScript +// object keeps its fields checked-dynamic, and assert.throws, assert.match +// and the expected-object form convert them to the regex or string the +// fields hold. +"use strict"; +const assert = require("assert"); + +const errMessages = { + auth: / auth/, + state: / state/, + length: /Invalid initialization vector/, + code: "ERR_CRYPTO_INVALID_IV", +}; + +const error = (message, code) => { + const e = new Error(message); + if (code) e.code = code; + return e; +}; + +assert.throws(() => { + throw error("Unsupported state or unable to authenticate data"); +}, errMessages.auth); +assert.throws(() => { + throw error("Invalid state for operation getAuthTag"); +}, errMessages.state); +assert.throws( + () => { + throw error("Invalid initialization vector", "ERR_CRYPTO_INVALID_IV"); + }, + { code: errMessages.code, message: errMessages.length }, +); +assert.match("unable to auth", errMessages.auth); +assert.doesNotMatch("no match here", errMessages.state); + +const report = (label, run) => { + try { + run(); + console.log(label, "passed"); + } catch (error) { + console.log(label, error.name, error.code, error.message.split("\n")[0]); + } +}; +report("wrong message", () => + assert.throws(() => { + throw error("something else"); + }, errMessages.length), +); +report("wrong code", () => + assert.throws( + () => { + throw error("Invalid initialization vector", "ERR_OTHER"); + }, + { code: errMessages.code }, + ), +); +report("match", () => assert.match("plain text", errMessages.auth)); +console.log("done"); diff --git a/tests/corpus/8180-pow2-quotients.ts b/tests/corpus/8180-pow2-quotients.ts new file mode 100644 index 000000000..f98d4e46e --- /dev/null +++ b/tests/corpus/8180-pow2-quotients.ts @@ -0,0 +1,57 @@ +// x / Math.pow(2, n) over every integer exponent from -1080 to 1030, against +// the same divisor read back from an array (an ordinary division): zeros, +// subnormals, values next to the limits, infinities and NaN, and a divisor of +// 2 ** n that is subnormal, zero or Infinity. Non-integer, signed-zero, +// infinite and NaN exponents give divisors that are not powers of two. +function bits(x: number): string { + const view = new DataView(new ArrayBuffer(8)); + view.setFloat64(0, x); + return view.getBigUint64(0).toString(16).padStart(16, "0"); +} + +const values = [ + 1, -1, 3, 0.1, -7.25, 0, -0, 5e-324, -5e-324, 2.2250738585072014e-308, 1.7976931348623157e308, + -1.7976931348623157e308, 4503599627370497, 123456789.123, Infinity, -Infinity, NaN, +]; +const divisors: number[] = []; +for (let n = -1080; n <= 1030; n++) divisors.push(Math.pow(2, n)); + +const scratch = new DataView(new ArrayBuffer(8)); +let digest = 0; +let mismatches = 0; +for (let n = -1080; n <= 1030; n++) { + const divisor = divisors[n + 1080]!; + for (const x of values) { + const quotient = x / Math.pow(2, n); + const plain = x / divisor; + scratch.setFloat64(0, quotient); + digest = (Math.imul(digest, 31) + scratch.getUint32(0)) | 0; + digest = (Math.imul(digest, 31) + scratch.getUint32(4)) | 0; + if (!Object.is(quotient, plain)) { + mismatches++; + if (mismatches <= 5) console.log("mismatch", x, n, bits(quotient), bits(plain)); + } + } +} +console.log("digest", (digest >>> 0).toString(16), "mismatches", mismatches); + +for (const n of [-1075, -1074, -1023, -1022, -1, 0, 1, 52, 1022, 1023, 1024]) { + console.log(n, bits(3 / Math.pow(2, n)), bits(-5e-324 / Math.pow(2, n)), bits(1.7976931348623157e308 / Math.pow(2, n))); +} +for (const e of [0.5, -0.5, -0, 1e-300, 1023.0000001, -1074.5, Infinity, -Infinity, NaN, 2 ** 31, -(2 ** 31)]) { + console.log("exponent", e, bits(10 / Math.pow(2, e)), bits(-0 / Math.pow(2, e))); +} + +// A divisor that changes every pass, and one computed once. +let total = 0; +for (let i = 0; i < 100000; i++) { + const shift = (i % 40) - 20; + total += (i * 7 + 3) / Math.pow(2, shift); +} +console.log("total", total); +let key = 12345; +const width = 34; +for (let i = 0; i < 100000; i++) { + key = (key - Math.floor(key / Math.pow(2, width)) * Math.pow(2, width)) * 4 + (i % 4); +} +console.log("key", key); diff --git a/tests/corpus/split-cjs-require-binding/chain-wrap.cjs b/tests/corpus/split-cjs-require-binding/chain-wrap.cjs new file mode 100644 index 000000000..435dcaeab --- /dev/null +++ b/tests/corpus/split-cjs-require-binding/chain-wrap.cjs @@ -0,0 +1,3 @@ +var chained; +chained = require("./chain.cjs"); +module.exports = chained; diff --git a/tests/corpus/split-cjs-require-binding/chain.cjs b/tests/corpus/split-cjs-require-binding/chain.cjs new file mode 100644 index 000000000..a279f456e --- /dev/null +++ b/tests/corpus/split-cjs-require-binding/chain.cjs @@ -0,0 +1 @@ +module.exports = require("./whole.cjs"); diff --git a/tests/corpus/split-cjs-require-binding/lib.cjs b/tests/corpus/split-cjs-require-binding/lib.cjs new file mode 100644 index 000000000..b318eb85c --- /dev/null +++ b/tests/corpus/split-cjs-require-binding/lib.cjs @@ -0,0 +1,5 @@ +console.log("lib: init"); +exports.n = 7; +exports.f = function (x) { + return x * 2; +}; diff --git a/tests/corpus/split-cjs-require-binding/main.cjs b/tests/corpus/split-cjs-require-binding/main.cjs new file mode 100644 index 000000000..974421bd3 --- /dev/null +++ b/tests/corpus/split-cjs-require-binding/main.cjs @@ -0,0 +1,55 @@ +console.log("main: start"); +var lib, whole; +lib = require("./lib.cjs"); +whole = require("./whole.cjs"); +console.log("main: after", lib.n, lib.f(3), whole(4)); +exports.fromLib = lib.f; +exports.whole = whole; +console.log("main: exported", exports.fromLib(5), whole(6)); +console.log("main: identity", exports.fromLib === lib.f, exports.whole === whole); +const re = require("./reexport.cjs"); +console.log("main: reexport", re(7)); +let later; +later = require("./lib.cjs"); +console.log("main: let", later.n); +const rx = require("./reexport-extra.cjs"); +console.log("main: reexport extra", rx(8), rx.extra); +const splitObject = { whole }; +console.log("main: shorthand value", splitObject.whole(10)); +var libAgain; +libAgain = require("./lib.cjs"); +const { n: splitN, f: splitF } = libAgain; +console.log("main: destructured split", splitN, splitF(4)); +var chained; +chained = require("./chain-wrap.cjs"); +console.log("main: chained", chained(11)); + +// Any later write, including a destructuring target, keeps ordinary storage. +var shorthand; +shorthand = require("./whole.cjs"); +({ shorthand } = { shorthand: "shorthand" }); +console.log("main: shorthand write", shorthand); +var renamed; +renamed = require("./whole.cjs"); +({ value: renamed } = { value: "renamed" }); +console.log("main: renamed write", renamed); +var nested; +nested = require("./whole.cjs"); +({ a: { nested } } = { a: { nested: "nested" } }); +console.log("main: nested write", nested); +var rest; +rest = require("./whole.cjs"); +({ ...rest } = { a: 1, b: 2 }); +console.log("main: rest write", rest.a, rest.b); +var array; +array = require("./whole.cjs"); +[array] = ["array"]; +console.log("main: array write", array); +var arrayRest; +arrayRest = require("./whole.cjs"); +[...arrayRest] = [1, 2]; +console.log("main: array-rest write", arrayRest[0], arrayRest[1]); +var each; +each = require("./whole.cjs"); +for ({ each } of [{ each: "each" }]) {} +console.log("main: for-of write", each); diff --git a/tests/corpus/split-cjs-require-binding/package.json b/tests/corpus/split-cjs-require-binding/package.json new file mode 100644 index 000000000..a3c15a7a6 --- /dev/null +++ b/tests/corpus/split-cjs-require-binding/package.json @@ -0,0 +1 @@ +{ "type": "commonjs" } diff --git a/tests/corpus/split-cjs-require-binding/reexport-extra.cjs b/tests/corpus/split-cjs-require-binding/reexport-extra.cjs new file mode 100644 index 000000000..584de98fe --- /dev/null +++ b/tests/corpus/split-cjs-require-binding/reexport-extra.cjs @@ -0,0 +1,6 @@ +var whole; +whole = require("./whole.cjs"); +console.log("extra: before", whole.extra, whole(9)); +module.exports = whole; +module.exports.extra = 1; +console.log("extra: after", whole.extra, module.exports.extra); diff --git a/tests/corpus/split-cjs-require-binding/reexport.cjs b/tests/corpus/split-cjs-require-binding/reexport.cjs new file mode 100644 index 000000000..9a931bdef --- /dev/null +++ b/tests/corpus/split-cjs-require-binding/reexport.cjs @@ -0,0 +1,4 @@ +console.log("reexport: init"); +var whole; +whole = require("./whole.cjs"); +module.exports = whole; diff --git a/tests/corpus/split-cjs-require-binding/whole.cjs b/tests/corpus/split-cjs-require-binding/whole.cjs new file mode 100644 index 000000000..31b476c4e --- /dev/null +++ b/tests/corpus/split-cjs-require-binding/whole.cjs @@ -0,0 +1,4 @@ +console.log("whole: init"); +module.exports = function whole(x) { + return x + 1; +}; diff --git a/tests/corpus/split-cjs-require-cycle/even.cjs b/tests/corpus/split-cjs-require-cycle/even.cjs new file mode 100644 index 000000000..94d74ea87 --- /dev/null +++ b/tests/corpus/split-cjs-require-cycle/even.cjs @@ -0,0 +1,10 @@ +var odd; +exports.name = "even"; +exports.isEven = function (n) { + return n === 0 ? true : odd.isOdd(n - 1); +}; +exports.describe = function (n) { + return n + " is " + (exports.isEven(n) ? "even" : "odd") + " (asked " + odd.name + ")"; +}; +odd = require("./odd.cjs"); +console.log("even: loaded"); diff --git a/tests/corpus/split-cjs-require-cycle/main.cjs b/tests/corpus/split-cjs-require-cycle/main.cjs new file mode 100644 index 000000000..9ec7997db --- /dev/null +++ b/tests/corpus/split-cjs-require-cycle/main.cjs @@ -0,0 +1,12 @@ +// Split require bindings (`var m; m = require("./x.cjs")`) that close a +// CommonJS cycle: each module publishes its exports before its require, and +// reads the other module's binding only in functions that run after both +// modules finish, the cycle shape the const form compiles too. One +// assignment parenthesizes its require. +console.log("main: start"); +var even, odd; +even = require("./even.cjs"); +odd = require("./odd.cjs"); +console.log(even.isEven(10), odd.isOdd(7), even.isEven(3)); +console.log(even.describe(4), "|", even.describe(9)); +console.log("odd calls", odd.calls(), even.name, odd.name); diff --git a/tests/corpus/split-cjs-require-cycle/odd.cjs b/tests/corpus/split-cjs-require-cycle/odd.cjs new file mode 100644 index 000000000..d449c28e8 --- /dev/null +++ b/tests/corpus/split-cjs-require-cycle/odd.cjs @@ -0,0 +1,12 @@ +var even; +let calls = 0; +exports.name = "odd"; +exports.isOdd = function (n) { + calls++; + return n === 0 ? false : even.isEven(n - 1); +}; +exports.calls = function () { + return calls; +}; +even = (require("./even.cjs")); +console.log("odd: loaded"); diff --git a/tests/corpus/split-cjs-require-cycle/package.json b/tests/corpus/split-cjs-require-cycle/package.json new file mode 100644 index 000000000..a3c15a7a6 --- /dev/null +++ b/tests/corpus/split-cjs-require-cycle/package.json @@ -0,0 +1 @@ +{ "type": "commonjs" } diff --git a/tests/corpus/typed-array-masked-index-stores.ts b/tests/corpus/typed-array-masked-index-stores.ts new file mode 100644 index 000000000..88a25b4c5 --- /dev/null +++ b/tests/corpus/typed-array-masked-index-stores.ts @@ -0,0 +1,40 @@ +// Several typed array accesses in one counted loop share an index that is +// not an affine function of the counter (a masked or remaindered counter). +// The loop versioning analysis records that such an index has no affine +// shape and reads the recorded result again at each later access. +const length = 64; +const bytes = new Uint8Array(length); +const words = new Int32Array(16); +const totals = new Float64Array(16); + +for (let i = 0; i < bytes.length; i++) { + const slot = i & 15; + words[slot] = words[slot]! + i; + totals[slot] = totals[slot]! + i * 0.5; + bytes[i] = slot; +} +console.log(Array.from(words).join(",")); +console.log(Array.from(totals).join(",")); +console.log(bytes.reduce((sum, value) => sum + value, 0)); + +const ring = new Uint16Array(8); +const seen = new Uint8Array(8); +for (let i = 0; i < length; i++) { + const at = i % 8; + ring[at] = ring[at]! * 3 + i; + seen[at] = seen[at]! + 1; +} +console.log(Array.from(ring).join(","), Array.from(seen).join(",")); + +function scatter(source: Uint8Array, mask: number): Uint32Array { + const out = new Uint32Array(mask + 1); + const counts = new Uint32Array(mask + 1); + for (let i = 0; i < source.length; i++) { + const bucket = (source[i]! + i) & mask; + out[bucket] = out[bucket]! + source[i]!; + counts[bucket] = counts[bucket]! + 1; + } + for (let i = 0; i < out.length; i++) out[i] = out[i]! * 10 + counts[i]!; + return out; +} +console.log(Array.from(scatter(bytes, 7)).join(",")); diff --git a/tests/coverage-fixtures/no-divergences.ts b/tests/coverage-fixtures/no-divergences.ts index 3739336e3..70409d319 100644 --- a/tests/coverage-fixtures/no-divergences.ts +++ b/tests/coverage-fixtures/no-divergences.ts @@ -1,6 +1,6 @@ // Ordinary code: identity-preserving calls, declaration-ordered literals, -// Latin-script comparisons, related-class casts, ISO dates and views of the -// global object report no divergence. +// Latin-script comparisons, related-class casts, ISO dates, views of the +// global object and a dictionary held as `{}` report no divergence. interface Item { name: string; qty: number; @@ -38,3 +38,17 @@ const COUNT = Symbol.for("no-divergences.count"); const globalState = globalThis as { [COUNT]?: { n: number } }; globalState[COUNT] = { n: 1 }; console.log(globalState[COUNT]?.n); + +// A dictionary held as `{}` comes back out as itself. +const counts: Record = { a: "x" }; +const opaque: {} = counts; +const again: Record = opaque; +again[counts["a"] ?? "a"] = "y"; +console.log(JSON.stringify(counts)); + +// A record stored in a dictionary binding and written through it stays +// the same object. +const named: { first: string } = { first: "a" }; +const byName: Record = named; +byName[named.first] = "b"; +console.log(JSON.stringify(named)); diff --git a/tests/diagnostics/fs-url-path-fences.ts b/tests/diagnostics/fs-url-path-fences.ts index 080c561e1..6b65bfac0 100644 --- a/tests/diagnostics/fs-url-path-fences.ts +++ b/tests/diagnostics/fs-url-path-fences.ts @@ -1,15 +1,16 @@ // URL paths whose conversion would run in a different order than Node's. import * as fs from "node:fs"; +import * as fsp from "node:fs/promises"; const url = new URL("file:///tmp/fs-url-path-fences"); -const encoding: BufferEncoding = process.argv.length > 9 ? "latin1" : "utf8"; const recursive = process.argv.length > 9; -// Node validates the string source before converting the URL destination. -fs.copyFileSync("/tmp/source", url); // Node validates the options before the path. -console.log(fs.readFileSync(url, encoding)); fs.mkdirSync(url, { recursive }); +void fsp.mkdir(url, { recursive }); // A literal's members are lowered one by one, so they cannot be evaluated // ahead of the conversion as one value. console.log(fs.statSync(url, { throwIfNoEntry: process.argv.length > 9 })); +// fs.promises checks the string source inside the call, after the +// conversion would have run. +void fsp.copyFile("/tmp/source", url); diff --git a/tests/diagnostics/index-signature-values.ts b/tests/diagnostics/index-signature-values.ts index 6c53b141c..1f3a01ba5 100644 --- a/tests/diagnostics/index-signature-values.ts +++ b/tests/diagnostics/index-signature-values.ts @@ -8,10 +8,6 @@ const bySymbol: { [s: symbol]: number } = {}; console.log(bySymbol); -// Storage is supported, but composite typed-array inspection is not. -const buffers: Record = {}; -console.log(buffers); - // Dual signatures whose value types intern DIFFERENTLY cannot share the // one store (tsc requires only assignability, but the store gives one // answer per key). diff --git a/tests/diagnostics/node-fallback-fence.ts b/tests/diagnostics/node-fallback-fence.ts index 86034f1ac..b044e22d3 100644 --- a/tests/diagnostics/node-fallback-fence.ts +++ b/tests/diagnostics/node-fallback-fence.ts @@ -30,9 +30,9 @@ const raw = readFileSync("/etc/hosts").toString(tty ? "hex" : "latin1"); // runt const intervalWithSignal = promiseInterval(1, "tick", {}); // AbortSignal options stay fenced const sleepWithSignal = promiseSleep(1, "tick", { signal: AbortSignal.timeout(5) }); // resolve values and AbortSignal options lower // The computed encoding is now part of the static Buffer surface. The -// one-shot zlib/raw/gzip codecs take Node's options, validated at run -// time; Brotli remains an explicit member fence. +// one-shot zlib/raw/gzip and Brotli codecs take Node's options, validated +// at run time. import { brotliCompressSync, deflateSync } from "node:zlib"; const packed = deflateSync("data", { level: 9, strategy: 1 }); // options lower -const brotli = brotliCompressSync(Buffer.from("data")); // outside the lowered family: fenced +const brotli = brotliCompressSync(Buffer.from("data")); // Brotli lowers too // The remaining imports continue the declared-but-not-lowered surface. diff --git a/tests/diagnostics/split-cjs-require-cycle/b.js b/tests/diagnostics/split-cjs-require-cycle/b.js new file mode 100644 index 000000000..ad5a7441a --- /dev/null +++ b/tests/diagnostics/split-cjs-require-cycle/b.js @@ -0,0 +1,7 @@ +var a; +a = require('./main.js'); +exports.fromB = 'b-value'; +exports.readA = function () { + return a.early + '/' + a.late; +}; +console.log('b sees a.early:', a.early, 'a.late:', a.late); diff --git a/tests/diagnostics/split-cjs-require-cycle/main.js b/tests/diagnostics/split-cjs-require-cycle/main.js new file mode 100644 index 000000000..286de459a --- /dev/null +++ b/tests/diagnostics/split-cjs-require-cycle/main.js @@ -0,0 +1,11 @@ +// A split require binding (`var b; b = require("./b.js")`) whose require +// closes a CommonJS cycle that top-level code can observe: b.js reads a.js's +// partial exports while a.js is still evaluating, which the compiled export +// table does not model. Preflight refuses it with SC1016, as it refuses the +// `const b = require("./b.js")` form; tests/corpus/split-cjs-require-cycle +// compiles the cycle shape both forms admit. +exports.early = 'a-early'; +var b; +b = require('./b.js'); +exports.late = 'a-late'; +console.log('a sees', b.fromB, b.readA()); diff --git a/tests/diagnostics/split-cjs-require-cycle/package.json b/tests/diagnostics/split-cjs-require-cycle/package.json new file mode 100644 index 000000000..a3c15a7a6 --- /dev/null +++ b/tests/diagnostics/split-cjs-require-cycle/package.json @@ -0,0 +1 @@ +{ "type": "commonjs" } diff --git a/tests/diagnostics/split-cjs-require-early/lib.js b/tests/diagnostics/split-cjs-require-early/lib.js new file mode 100644 index 000000000..2a9669e12 --- /dev/null +++ b/tests/diagnostics/split-cjs-require-early/lib.js @@ -0,0 +1,8 @@ +'use strict'; + +/** @param {string} who */ +function greet(who) { + return `hello ${who}`; +} + +module.exports = { greet }; diff --git a/tests/diagnostics/split-cjs-require-early/main.js b/tests/diagnostics/split-cjs-require-early/main.js new file mode 100644 index 000000000..ae1d8d770 --- /dev/null +++ b/tests/diagnostics/split-cjs-require-early/main.js @@ -0,0 +1,21 @@ +// A split require binding (`let lib;` then `lib = require(...)`) that code +// above the assignment can reach: Node reads undefined there, a value the +// compiled module alias cannot hold, so the assignment keeps a named SC1013 +// fence. Assigned before any such code, the binding compiles +// (tests/corpus/split-cjs-require-binding). +'use strict'; + +let lib; +console.log('boot', helper()); +lib = require('./lib.js'); + +// The same with the require parenthesized. +let wrapped; +console.log('peek', wrapped === undefined); +wrapped = (require('./lib.js')); + +function helper() { + return lib === undefined ? 'not loaded' : lib.greet('late'); +} + +console.log(helper()); diff --git a/tests/diagnostics/split-cjs-require-early/package.json b/tests/diagnostics/split-cjs-require-early/package.json new file mode 100644 index 000000000..a3c15a7a6 --- /dev/null +++ b/tests/diagnostics/split-cjs-require-early/package.json @@ -0,0 +1 @@ +{ "type": "commonjs" } diff --git a/tests/diagnostics/unions.ts b/tests/diagnostics/unions.ts index ccf62f40e..ddacb8015 100644 --- a/tests/diagnostics/unions.ts +++ b/tests/diagnostics/unions.ts @@ -60,14 +60,6 @@ const bareN = null; // honest text (JS prints "[object Object]") and stays fenced. const templated = `${mkAB()}`; -// `x == null` lowers as the null-or-undefined tag test — but a union with -// BOTH unit arms needs the operand twice, so an effectful operand (a call) -// gets its own fence pointing at a const binding. -function mkNullish(): string | null | undefined { - return null; -} -const looseCall = mkNullish() == null; - // A DECLARED `T | string` param infers nothing for T (no union // unification); the body's use of T then fails with the instantiation. function tagOr(x: T | string): T { diff --git a/tests/fixtures/event-loop/stdin-for-await-buffers.mjs b/tests/fixtures/event-loop/stdin-for-await-buffers.mjs new file mode 100644 index 000000000..d64ae460a --- /dev/null +++ b/tests/fixtures/event-loop/stdin-for-await-buffers.mjs @@ -0,0 +1,10 @@ +// for await over process.stdin yields Buffers: Buffer.isBuffer holds and +// indexOf takes a byte and a start offset (only chunking-independent facts +// are printed). +const chunks = []; +for await (const chunk of process.stdin) chunks.push(chunk); +console.log('buffers', chunks.every((chunk) => Buffer.isBuffer(chunk))); +const all = Buffer.concat(chunks); +const newlines = []; +for (let at = all.indexOf(10); at !== -1; at = all.indexOf(10, at + 1)) newlines.push(at); +console.log('newlines', newlines.join(','), all.subarray(newlines[0] + 1).indexOf('#')); diff --git a/tests/fixtures/event-loop/stdio-readable-backpressure.mjs b/tests/fixtures/event-loop/stdio-readable-backpressure.mjs new file mode 100644 index 000000000..df2afb18f --- /dev/null +++ b/tests/fixtures/event-loop/stdio-readable-backpressure.mjs @@ -0,0 +1,27 @@ +// 'readable', 'data' and resume() together, with no read() for a while: +// 'readable' keeps the stream paused, so it stops reading at its read-ahead +// mark until a read drains it, and 'data' sees what read() returns. +const input = process.stdin; +let draining = false; +let peak = 0; +let dataBytes = 0; +let readBytes = 0; +const drain = () => { + let chunk; + while ((chunk = input.read()) !== null) readBytes += chunk.length; +}; +input.on('data', (chunk) => { + dataBytes += chunk.length; +}); +input.on('readable', () => { + peak = Math.max(peak, input.readableLength); + if (draining) drain(); +}); +input.resume(); +setTimeout(() => { + peak = Math.max(peak, input.readableLength); + console.log('held below 128 KiB while not draining', peak <= 131072); + draining = true; + drain(); +}, 400); +input.on('end', () => console.log('read', readBytes, 'data', dataBytes)); diff --git a/tests/fixtures/event-loop/stdio-readable-large-size.mjs b/tests/fixtures/event-loop/stdio-readable-large-size.mjs new file mode 100644 index 000000000..f1f44edce --- /dev/null +++ b/tests/fixtures/event-loop/stdio-readable-large-size.mjs @@ -0,0 +1,9 @@ +// read(size) above the 64 KiB read-ahead mark: 'readable' keeps firing as +// input arrives until the requested size is buffered. +const input = process.stdin; +const sizes = []; +input.on('readable', () => { + let chunk; + while ((chunk = input.read(150000)) !== null) sizes.push(chunk.length); +}); +input.on('end', () => console.log(sizes.join(','))); diff --git a/tests/fixtures/event-loop/stdio-readable-once-rest.mjs b/tests/fixtures/event-loop/stdio-readable-once-rest.mjs new file mode 100644 index 000000000..81eae144b --- /dev/null +++ b/tests/fixtures/event-loop/stdio-readable-once-rest.mjs @@ -0,0 +1,12 @@ +// A once('readable') listener that reads part of the input: the rest stays +// buffered for a 'data' listener added afterwards. +const input = process.stdin; +input.once('readable', () => { + const head = input.read(3); + console.log('head', head === null ? null : head.toString('ascii')); + setTimeout(() => { + const rest = []; + input.on('data', (chunk) => rest.push(chunk.toString('ascii'))); + input.on('end', () => console.log('rest', rest.join(''))); + }, 50); +}); diff --git a/tests/fixtures/event-loop/stdio-readable-size.mjs b/tests/fixtures/event-loop/stdio-readable-size.mjs new file mode 100644 index 000000000..9ff76dafe --- /dev/null +++ b/tests/fixtures/event-loop/stdio-readable-size.mjs @@ -0,0 +1,18 @@ +// Fixed-size reads of stdin: read(n) answers null until n bytes are +// buffered, and the rest once the input ended. +const input = process.stdin; +const chunks = []; +const counts = []; +input.on('readable', () => { + let reads = 0; + let chunk; + while ((chunk = input.read(4)) !== null) { + chunks.push(chunk.toString('ascii')); + reads++; + } + counts.push(reads); +}); +input.on('end', () => { + console.log(chunks.join('|')); + console.log(counts.join(',')); +}); diff --git a/tests/fixtures/event-loop/stdio-readable.mjs b/tests/fixtures/event-loop/stdio-readable.mjs new file mode 100644 index 000000000..324a4b57b --- /dev/null +++ b/tests/fixtures/event-loop/stdio-readable.mjs @@ -0,0 +1,19 @@ +// process.stdin in paused mode through 'readable': each event drains the +// buffer with read(), one more event follows EOF, and 'end' comes after the +// read that finds the buffer empty. +const input = process.stdin; +const events = []; +let text = ''; +input.on('readable', () => { + let reads = 0; + let chunk; + while ((chunk = input.read()) !== null) { + text += String(chunk); + reads++; + } + events.push(`readable ${reads}`); +}); +input.on('end', () => { + console.log(events.join(', ')); + console.log(JSON.stringify(text), input.readableLength); +}); diff --git a/tests/fixtures/node-types/fenced.ts b/tests/fixtures/node-types/fenced.ts index 0ddf0ea3f..0d90e8cac 100644 --- a/tests/fixtures/node-types/fenced.ts +++ b/tests/fixtures/node-types/fenced.ts @@ -45,9 +45,8 @@ console.log(win32.sep); const u = new URL("https://example.com/x?a=1"); console.log(URL.createObjectURL(new Blob(["data"]))); u.searchParams.get("a"); -/* The one-shot zlib/raw/gzip codecs take Node's options (the deflateSync - * call lowers), while Brotli remains a member-qualified fence with the - * lowered family named. */ +/* The one-shot zlib/raw/gzip and Brotli codecs take Node's options (the + * deflateSync and brotliCompressSync calls lower). */ import { brotliCompressSync, deflateSync } from "zlib"; deflateSync("data", { level: 9, strategy: 1 }); brotliCompressSync(Buffer.from("data")); diff --git a/tests/fixtures/node-types/fs-url-fallible.ts b/tests/fixtures/node-types/fs-url-fallible.ts new file mode 100644 index 000000000..da86879d5 --- /dev/null +++ b/tests/fixtures/node-types/fs-url-fallible.ts @@ -0,0 +1,19 @@ +import { existsSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { readFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { pathToFileURL } from "node:url"; + +const dir = mkdtempSync(join(tmpdir(), "node-types-url-")); +const file = pathToFileURL(join(dir, "a.txt")); +writeFileSync(file, "hi"); +// existsSync answers false for a URL it cannot convert. +console.log(existsSync(file), existsSync(new URL("http://example.com/"))); +// fs.promises functions reject for a URL they cannot convert. +readFile(file, "utf8") + .then((text) => console.log(text)) + .then(() => readFile(new URL("file://example.com/a.txt"), "utf8")) + .catch((error: unknown) => { + if (error instanceof Error) console.log((error as NodeJS.ErrnoException).code); + rmSync(dir, { recursive: true }); + }); diff --git a/tests/fixtures/node-types/fs-url-path-fences.ts b/tests/fixtures/node-types/fs-url-path-fences.ts deleted file mode 100644 index 4ae142189..000000000 --- a/tests/fixtures/node-types/fs-url-path-fences.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { existsSync } from "node:fs"; -import { readFile, stat } from "node:fs/promises"; - -const url = new URL("file:///tmp/node-types-url-fences"); -// existsSync answers false for a URL it cannot convert. -console.log(existsSync(url)); -// The fs.promises functions reject for a URL they cannot convert. -void readFile(url, "utf8"); -void stat(url); diff --git a/tests/fixtures/npm/cases/hono-zod-default-hook/main.ts b/tests/fixtures/npm/cases/hono-zod-default-hook/main.ts new file mode 100644 index 000000000..9981e7154 --- /dev/null +++ b/tests/fixtures/npm/cases/hono-zod-default-hook/main.ts @@ -0,0 +1,38 @@ +// @hono/zod-validator without a hook: a failed check answers 400 with the +// whole safeParse result serialized, so the ZodError's own enumerable +// properties (name, then message) and their order reach the client. +import { zValidator } from "@hono/zod-validator"; +import { Hono } from "hono"; +import { z } from "zod"; + +const Item = z.object({ title: z.string().min(2), qty: z.number().int().positive() }); + +const app = new Hono(); +app.post("/items", zValidator("json", Item), (c) => { + const item = c.req.valid("json"); + return c.json({ created: item.title, qty: item.qty }, 201); +}); +app.get("/items", zValidator("query", z.object({ limit: z.coerce.number().int().max(5) })), (c) => { + return c.json({ limit: c.req.valid("query").limit }); +}); + +const post = (body: unknown) => + app.request("/items", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body) }); + +const show = async (label: string, res: Response | Promise) => { + const r = await res; + console.log(label, r.status, await r.text()); +}; + +await show("ok", post({ title: "pen", qty: 2 })); +await show("bad-title", post({ title: "p", qty: 2 })); +await show("bad-both", post({ title: 3, qty: -1 })); +await show("query-ok", app.request("/items?limit=4")); +await show("query-bad", app.request("/items?limit=9")); + +const result = Item.safeParse({ title: "x", qty: 0 }); +if (!result.success) { + const e = result.error; + console.log(e.name, e instanceof Error, Object.keys(e).join(",")); + console.log(JSON.stringify(e)); +} diff --git a/tests/fixtures/npm/cases/hono-zod-default-hook/package.json b/tests/fixtures/npm/cases/hono-zod-default-hook/package.json new file mode 100644 index 000000000..a734aaddb --- /dev/null +++ b/tests/fixtures/npm/cases/hono-zod-default-hook/package.json @@ -0,0 +1 @@ +{ "name": "hono-zod-default-hook-case", "private": true, "type": "module" } diff --git a/tests/fixtures/npm/cases/zod4-record/main.ts b/tests/fixtures/npm/cases/zod4-record/main.ts new file mode 100644 index 000000000..b43eaebab --- /dev/null +++ b/tests/fixtures/npm/cases/zod4-record/main.ts @@ -0,0 +1,37 @@ +// zod 4's z.record and z.partialRecord accept only plain objects. Its check +// reads the value's constructor, that constructor's prototype, and whether +// the prototype has its own isPrototypeOf, so it needs Object.prototype's +// reflection to match Node. +import { z } from "zod"; + +const Scores = z.record(z.string(), z.number().int()); +const Flags = z.record(z.enum(["a", "b"]), z.boolean()); +const Partial = z.partialRecord(z.enum(["x", "y", "z"]), z.string()); +const Nested = z.object({ name: z.string(), meta: z.record(z.string(), z.record(z.string(), z.number())) }); + +const show = (label: string, schema: z.ZodType, value: unknown): void => { + const r = schema.safeParse(value); + if (r.success) { + console.log(label, "ok", JSON.stringify(r.data)); + } else { + console.log(label, "fail", r.error.issues.map((i) => `${i.path.join(".")}:${i.code}:${i.message}`).join(" | ")); + } +}; + +show("scores", Scores, { alice: 3, bob: 7 }); +show("scores-empty", Scores, {}); +show("scores-bad-value", Scores, { alice: 1.5 }); +show("scores-array", Scores, [1, 2]); +show("scores-null-proto", Scores, Object.assign(Object.create(null), { k: 1 })); +show("scores-parsed", Scores, JSON.parse('{"x":1,"y":2}')); +show("flags", Flags, { a: true, b: false }); +show("flags-missing", Flags, { a: true }); +show("flags-extra", Flags, { a: true, b: true, c: false }); +show("partial", Partial, { y: "why" }); +show("nested", Nested, { name: "n", meta: { one: { two: 2 } } }); +show("nested-bad", Nested, { name: "n", meta: { one: [] } }); + +class Point { + x = 1; +} +show("class-instance", Scores, new Point()); diff --git a/tests/fixtures/npm/cases/zod4-record/package.json b/tests/fixtures/npm/cases/zod4-record/package.json new file mode 100644 index 000000000..82c365084 --- /dev/null +++ b/tests/fixtures/npm/cases/zod4-record/package.json @@ -0,0 +1 @@ +{ "name": "zod4-record-case", "private": true, "type": "module" } diff --git a/tests/fixtures/self-hosting/llvm-layouts.ts b/tests/fixtures/self-hosting/llvm-layouts.ts index 6ddf3ca3a..36d55bddf 100644 --- a/tests/fixtures/self-hosting/llvm-layouts.ts +++ b/tests/fixtures/self-hosting/llvm-layouts.ts @@ -119,7 +119,8 @@ try { }, ); virtualBorrows = new VirtualBorrows(mod, graph, functions, lifetimes.borrowed); - const classObjects = new Map(request.classObjects.map((name) => [name, { nameSym: `@name_${mangleClassObj(name)}` }])); + const classObjects: Map = new Map(); + for (const name of request.classObjects) classObjects.set(name, { nameSym: `@name_${mangleClassObj(name)}`, baseNameSym: null }); const typeName = (type: IrType): string => type.kind === "void" ? "void" : type.kind === "f64" || type.kind === "date" ? "double" : type.kind === "bool" ? "i1" : "ptr"; // Mirrors the emitter: whole-program int32 fields store the exact i32. const layouts = emitLlvmLayouts(host, mod, graph, classObjects, functions, typeName, undefined, analyzeInt32Slots(mod)); diff --git a/tests/harness/__snapshots__/fs-url-path-fences.ts.txt b/tests/harness/__snapshots__/fs-url-path-fences.ts.txt index 1a53f8df5..1b4642d32 100644 --- a/tests/harness/__snapshots__/fs-url-path-fences.ts.txt +++ b/tests/harness/__snapshots__/fs-url-path-fences.ts.txt @@ -1,35 +1,35 @@ -fs-url-path-fences.ts:9:1 - error SC2020: 'copyFileSync with a string path before a URL path' is part of the standard library types but has no scriptc lowering yet +fs-url-path-fences.ts:9:19 - error SC2020: 'mkdirSync with a URL path and options that are not literals' is part of the standard library types but has no scriptc lowering yet - 8 | // Node validates the string source before converting the URL destination. - 9 | fs.copyFileSync("/tmp/source", url); - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 10 | // Node validates the options before the path. - - hint: convert the URL first: fileURLToPath(url) from node:url - -fs-url-path-fences.ts:11:34 - error SC2020: 'readFileSync with a URL path and options that are not literals' is part of the standard library types but has no scriptc lowering yet - - 10 | // Node validates the options before the path. - 11 | console.log(fs.readFileSync(url, encoding)); - | ^~~~~~~~ - 12 | fs.mkdirSync(url, { recursive }); - - hint: convert the URL first: fileURLToPath(url) from node:url - -fs-url-path-fences.ts:12:19 - error SC2020: 'mkdirSync with a URL path and options that are not literals' is part of the standard library types but has no scriptc lowering yet - - 11 | console.log(fs.readFileSync(url, encoding)); - 12 | fs.mkdirSync(url, { recursive }); + 8 | // Node validates the options before the path. + 9 | fs.mkdirSync(url, { recursive }); | ^~~~~~~~~~~~~ - 13 | // A literal's members are lowered one by one, so they cannot be evaluated + 10 | void fsp.mkdir(url, { recursive }); hint: convert the URL first: fileURLToPath(url) from node:url -fs-url-path-fences.ts:15:30 - error SC2020: 'statSync with a URL path and a later literal that has effects' is part of the standard library types but has no scriptc lowering yet +fs-url-path-fences.ts:10:21 - error SC2020: 'fs.promises.mkdir with a URL path and options that are not literals' is part of the standard library types but has no scriptc lowering yet - 14 | // ahead of the conversion as one value. - 15 | console.log(fs.statSync(url, { throwIfNoEntry: process.argv.length > 9 })); + 9 | fs.mkdirSync(url, { recursive }); + 10 | void fsp.mkdir(url, { recursive }); + | ^~~~~~~~~~~~~ + 11 | // A literal's members are lowered one by one, so they cannot be evaluated + + hint: convert the URL first: fileURLToPath(url) from node:url + +fs-url-path-fences.ts:13:30 - error SC2020: 'statSync with a URL path and a later literal that has effects' is part of the standard library types but has no scriptc lowering yet + + 12 | // ahead of the conversion as one value. + 13 | console.log(fs.statSync(url, { throwIfNoEntry: process.argv.length > 9 })); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 16 | + 14 | // fs.promises checks the string source inside the call, after the + + hint: convert the URL first: fileURLToPath(url) from node:url + +fs-url-path-fences.ts:16:6 - error SC2020: 'fs.promises.copyFile with a string path before a URL path' is part of the standard library types but has no scriptc lowering yet + + 15 | // conversion would have run. + 16 | void fsp.copyFile("/tmp/source", url); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 17 | hint: convert the URL first: fileURLToPath(url) from node:url \ No newline at end of file diff --git a/tests/harness/__snapshots__/index-signature-values.ts.txt b/tests/harness/__snapshots__/index-signature-values.ts.txt index 084d6a259..1c037086b 100644 --- a/tests/harness/__snapshots__/index-signature-values.ts.txt +++ b/tests/harness/__snapshots__/index-signature-values.ts.txt @@ -7,18 +7,11 @@ index-signature-values.ts:8:7 - error SC2006: values of type '{ [s: symbol]: num hint: string- and number-keyed index signatures over the supported value types compile directly; symbol keys and dual signatures with unequal value types have no lowering -index-signature-values.ts:13:13 - error SC1090: console.log of '{ [key: string]: Uint8Array }' values (Uint8Array and Buffer values inside composites have no inspect lowering yet (Buffer's form vs Uint8Array's is not recorded in the static type here)) are not supported yet +index-signature-values.ts:14:7 - error SC2006: values of type '{ [k: string]: string | number; [n: number]: number; }' cannot be compiled: this index signature is outside the supported shape (string or number keys; values limited to numbers, strings, booleans, records, classes, arrays, unions, functions, Maps, Sets, RegExps, Dates, Promises, or 'unknown') - 12 | const buffers: Record = {}; - 13 | console.log(buffers); - | ^~~~~~~ - 14 | - -index-signature-values.ts:18:7 - error SC2006: values of type '{ [k: string]: string | number; [n: number]: number; }' cannot be compiled: this index signature is outside the supported shape (string or number keys; values limited to numbers, strings, booleans, records, classes, arrays, unions, functions, Maps, Sets, RegExps, Dates, Promises, or 'unknown') - - 17 | // answer per key). - 18 | const dual: { [k: string]: string | number; [n: number]: number } = {}; + 13 | // answer per key). + 14 | const dual: { [k: string]: string | number; [n: number]: number } = {}; | ^~~~ - 19 | console.log(dual); + 15 | console.log(dual); hint: string- and number-keyed index signatures over the supported value types compile directly; symbol keys and dual signatures with unequal value types have no lowering \ No newline at end of file diff --git a/tests/harness/__snapshots__/node-fallback-fence.ts.txt b/tests/harness/__snapshots__/node-fallback-fence.ts.txt index 9670ca7d0..6cd12532e 100644 --- a/tests/harness/__snapshots__/node-fallback-fence.ts.txt +++ b/tests/harness/__snapshots__/node-fallback-fence.ts.txt @@ -14,13 +14,4 @@ node-fallback-fence.ts:30:28 - error SC2020: 'timers/promises.setInterval with 3 | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 | const sleepWithSignal = promiseSleep(1, "tick", { signal: AbortSignal.timeout(5) }); // resolve values and AbortSignal options lower - hint: the lowered form is setInterval(delay, value) with an explicit yielded value; AbortSignal options are not supported yet - -node-fallback-fence.ts:37:16 - error SC2020: 'zlib.brotliCompressSync' is part of the standard library types but has no scriptc lowering yet - - 36 | const packed = deflateSync("data", { level: 9, strategy: 1 }); // options lower - 37 | const brotli = brotliCompressSync(Buffer.from("data")); // outside the lowered family: fenced - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 38 | // The remaining imports continue the declared-but-not-lowered surface. - - hint: Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface \ No newline at end of file + hint: the lowered form is setInterval(delay, value) with an explicit yielded value; AbortSignal options are not supported yet \ No newline at end of file diff --git a/tests/harness/__snapshots__/node-types-fenced.txt b/tests/harness/__snapshots__/node-types-fenced.txt index d0aa4a140..32eb08fba 100644 --- a/tests/harness/__snapshots__/node-types-fenced.txt +++ b/tests/harness/__snapshots__/node-types-fenced.txt @@ -79,173 +79,164 @@ fenced.ts:46:13 - error SC2020: 'URL.createObjectURL' is typed by @types/node bu hint: protocol, origin, username, password, pathname, href, host, hostname, port, search, hash, searchParams, toString(), and toJSON() are the supported URL members -fenced.ts:53:1 - error SC2020: 'zlib.brotliCompressSync' is typed by @types/node but has no scriptc lowering yet +fenced.ts:61:71 - error SC2020: 'a createSecureServer SNICallback of 'undefined' values' is part of the standard library types but has no scriptc lowering yet - 52 | deflateSync("data", { level: 9, strategy: 1 }); - 53 | brotliCompressSync(Buffer.from("data")); - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 54 | /* The http2 compatibility slice's @types/node-world fences (divergence - - hint: Brotli needs a Brotli codec, which the static runtime does not vendor — the deflate/inflate, raw, gzip/gunzip, and unzip sync/callback forms with Node's options, crc32, and the Deflate/Inflate/Gzip/Gunzip/DeflateRaw/InflateRaw/Unzip streams are the lowered zlib surface - -fenced.ts:62:71 - error SC2020: 'a createSecureServer SNICallback of 'undefined' values' is part of the standard library types but has no scriptc lowering yet - - 61 | import * as http2 from "node:http2"; - 62 | http2.createSecureServer({ allowHTTP1: true, cert: "pem", key: "pem", SNICallback: undefined }); + 60 | import * as http2 from "node:http2"; + 61 | http2.createSecureServer({ allowHTTP1: true, cert: "pem", key: "pem", SNICallback: undefined }); | ^~~~~~~~~~~~~~~~~~~~~~ - 63 | http2.createSecureServer({ + 62 | http2.createSecureServer({ hint: SNICallback lowers as a direct option or the conditional spread ...(x ? { SNICallback: x } : {}) — the callback is (servername, cb) => void with cb: (err: Error | null, ctx?: tls.SecureContext) => void -fenced.ts:67:3 - error SC2020: 'createSecureServer options with a conditional spread' is part of the standard library types but has no scriptc lowering yet +fenced.ts:66:3 - error SC2020: 'createSecureServer options with a conditional spread' is part of the standard library types but has no scriptc lowering yet - 66 | key: "pem", - 67 | ...(1 ? { SNICallback: undefined } : {}), + 65 | key: "pem", + 66 | ...(1 ? { SNICallback: undefined } : {}), | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 68 | }); + 67 | }); hint: the lowered conditional spread is exactly ...(x ? { SNICallback: x } : {}) — the included value must BE the condition -fenced.ts:69:71 - error SC2020: 'createSecureServer option 'streamResetBurst' with a non-literal value' is part of the standard library types but has no scriptc lowering yet +fenced.ts:68:71 - error SC2020: 'createSecureServer option 'streamResetBurst' with a non-literal value' is part of the standard library types but has no scriptc lowering yet - 68 | }); - 69 | http2.createSecureServer({ allowHTTP1: true, cert: "pem", key: "pem", streamResetBurst: 1 + 0 }); + 67 | }); + 68 | http2.createSecureServer({ allowHTTP1: true, cert: "pem", key: "pem", streamResetBurst: 1 + 0 }); | ^~~~~~~~~~~~~~~~~~~~~~~ - 70 | http2.connect("https://localhost"); + 69 | http2.connect("https://localhost"); hint: h2 session-tuning options are accepted with literal values but are not applied yet -fenced.ts:76:1 - error SC2020: 'crypto.publicEncrypt' is typed by @types/node but has no scriptc lowering yet +fenced.ts:75:1 - error SC2020: 'crypto.publicEncrypt' is typed by @types/node but has no scriptc lowering yet - 75 | import { createCipheriv, publicEncrypt, secureHeapUsed, setFips } from "node:crypto"; - 76 | publicEncrypt("key", Buffer.alloc(1)); + 74 | import { createCipheriv, publicEncrypt, secureHeapUsed, setFips } from "node:crypto"; + 75 | publicEncrypt("key", Buffer.alloc(1)); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 77 | createCipheriv("aes-128-ocb", Buffer.alloc(16), Buffer.alloc(12), { authTagLength: 16 }); + 76 | createCipheriv("aes-128-ocb", Buffer.alloc(16), Buffer.alloc(12), { authTagLength: 16 }); hint: RSA encryption has no lowering — the asymmetric crypto surface is RSA and EC KeyObjects (generateKeyPair, createPrivateKey, createPublicKey), sign, verify, createSign, createVerify, createECDH, and createDiffieHellman -fenced.ts:77:16 - error SC2020: 'crypto.createCipheriv with cipher 'aes-128-ocb'' is part of the standard library types but has no scriptc lowering yet +fenced.ts:76:16 - error SC2020: 'crypto.createCipheriv with cipher 'aes-128-ocb'' is part of the standard library types but has no scriptc lowering yet - 76 | publicEncrypt("key", Buffer.alloc(1)); - 77 | createCipheriv("aes-128-ocb", Buffer.alloc(16), Buffer.alloc(12), { authTagLength: 16 }); + 75 | publicEncrypt("key", Buffer.alloc(1)); + 76 | createCipheriv("aes-128-ocb", Buffer.alloc(16), Buffer.alloc(12), { authTagLength: 16 }); | ^~~~~~~~~~~~~ - 78 | secureHeapUsed(); + 77 | secureHeapUsed(); hint: the supported ciphers are aes-128, aes-192 and aes-256 in cbc, ctr, gcm, ccm, ecb, cfb, cfb8, cfb1 and ofb modes and their wrap, wrap-pad, wrap-inv and wrap-pad-inv key wraps, des-ede3 in cbc, ecb, cfb, cfb8, cfb1 and ofb modes, des-ede in cbc, ecb, cfb and ofb modes, chacha20, and chacha20-poly1305 -fenced.ts:78:1 - error SC2020: 'crypto.secureHeapUsed' is typed by @types/node but has no scriptc lowering yet +fenced.ts:77:1 - error SC2020: 'crypto.secureHeapUsed' is typed by @types/node but has no scriptc lowering yet - 77 | createCipheriv("aes-128-ocb", Buffer.alloc(16), Buffer.alloc(12), { authTagLength: 16 }); - 78 | secureHeapUsed(); + 76 | createCipheriv("aes-128-ocb", Buffer.alloc(16), Buffer.alloc(12), { authTagLength: 16 }); + 77 | secureHeapUsed(); | ^~~~~~~~~~~~~~~~ - 79 | setFips(false); + 78 | setFips(false); hint: the type checker sees everything @types/node declares, but only the supported surface compiles (https://scriptc.dev/limitations) -fenced.ts:79:1 - error SC2020: 'crypto.setFips' is typed by @types/node but has no scriptc lowering yet +fenced.ts:78:1 - error SC2020: 'crypto.setFips' is typed by @types/node but has no scriptc lowering yet - 78 | secureHeapUsed(); - 79 | setFips(false); + 77 | secureHeapUsed(); + 78 | setFips(false); | ^~~~~~~~~~~~~~ - 80 | fetch("https://example.invalid/", { + 79 | fetch("https://example.invalid/", { hint: a compiled binary has no FIPS provider to enable, and Node itself throws on setFips(true) in a non-FIPS build — getFips() answers 0 here -fenced.ts:81:3 - error SC2020: 'RequestInit option 'integrity' in a static build' is typed by @types/node but has no scriptc lowering yet +fenced.ts:80:3 - error SC2020: 'RequestInit option 'integrity' in a static build' is typed by @types/node but has no scriptc lowering yet - 80 | fetch("https://example.invalid/", { - 81 | integrity: "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + 79 | fetch("https://example.invalid/", { + 80 | integrity: "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 82 | }); + 81 | }); hint: the compiler does not preserve this RequestInit member's conversion or transport behavior -fenced.ts:85:3 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet +fenced.ts:84:3 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet - 84 | const body = (await fetch(url)).body!; - 85 | body.tee(); + 83 | const body = (await fetch(url)).body!; + 84 | body.tee(); | ^~~~~~~~ - 86 | const tee = body.tee; + 85 | const tee = body.tee; hint: this operation is outside the native readable-stream implementation -fenced.ts:86:15 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet +fenced.ts:85:15 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet - 85 | body.tee(); - 86 | const tee = body.tee; + 84 | body.tee(); + 85 | const tee = body.tee; | ^~~~~~~~ - 87 | body["tee"](); + 86 | body["tee"](); hint: this operation is outside the native readable-stream implementation -fenced.ts:87:3 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet +fenced.ts:86:3 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet - 86 | const tee = body.tee; - 87 | body["tee"](); + 85 | const tee = body.tee; + 86 | body["tee"](); | ^~~~~~~~~~~ - 88 | const bracketTee = body["tee"]; + 87 | const bracketTee = body["tee"]; hint: this operation is outside the native readable-stream implementation -fenced.ts:88:22 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet +fenced.ts:87:22 - error SC2020: 'ReadableStream.tee' is typed by @types/node but has no scriptc lowering yet - 87 | body["tee"](); - 88 | const bracketTee = body["tee"]; + 86 | body["tee"](); + 87 | const bracketTee = body["tee"]; | ^~~~~~~~~~~ - 89 | } + 88 | } hint: this operation is outside the native readable-stream implementation -fenced.ts:94:23 - error SC2020: 'util.callbackify into a callback whose error parameter excludes null' is part of the standard library types but has no scriptc lowering yet +fenced.ts:93:23 - error SC2020: 'util.callbackify into a callback whose error parameter excludes null' is part of the standard library types but has no scriptc lowering yet - 93 | import { callbackify } from "node:util"; - 94 | const callbackified = callbackify(async (n: number) => n); + 92 | import { callbackify } from "node:util"; + 93 | const callbackified = callbackify(async (n: number) => n); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 95 | void callbackified; + 94 | void callbackified; hint: Node calls back with a null error on success; type the binding's callback as (err: NodeJS.ErrnoException | null, ...) => void -fenced.ts:100:12 - error SC2020: 'crypto.createECDH with curve 'sect163k1'' is part of the standard library types but has no scriptc lowering yet +fenced.ts:99:12 - error SC2020: 'crypto.createECDH with curve 'sect163k1'' is part of the standard library types but has no scriptc lowering yet - 99 | import { createECDH } from "node:crypto"; - 100 | createECDH("sect163k1"); + 98 | import { createECDH } from "node:crypto"; + 99 | createECDH("sect163k1"); | ^~~~~~~~~~~ - 101 | createECDH("prime256v1").computeSecret(Buffer.alloc(65), "hex"); + 100 | createECDH("prime256v1").computeSecret(Buffer.alloc(65), "hex"); hint: the supported curves are prime192v1, secp224r1, prime256v1, secp384r1, secp521r1, secp192k1, secp224k1, secp256k1, brainpoolP256r1, brainpoolP384r1, and brainpoolP512r1 -fenced.ts:101:1 - error SC2020: 'ECDH.computeSecret(key, encoding) with a Buffer or view key' is part of the standard library types but has no scriptc lowering yet +fenced.ts:100:1 - error SC2020: 'ECDH.computeSecret(key, encoding) with a Buffer or view key' is part of the standard library types but has no scriptc lowering yet - 100 | createECDH("sect163k1"); - 101 | createECDH("prime256v1").computeSecret(Buffer.alloc(65), "hex"); + 99 | createECDH("sect163k1"); + 100 | createECDH("prime256v1").computeSecret(Buffer.alloc(65), "hex"); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 102 | /* DiffieHellman's Object.prototype members. */ + 101 | /* DiffieHellman's Object.prototype members. */ hint: Node reads the second argument as the key's input encoding and answers a Buffer; pass the output encoding third: computeSecret(key, undefined, encoding) -fenced.ts:104:1 - error SC2020: 'DiffieHellman.toString' is part of the standard library types but has no scriptc lowering yet +fenced.ts:103:1 - error SC2020: 'DiffieHellman.toString' is part of the standard library types but has no scriptc lowering yet - 103 | import { createDiffieHellman } from "node:crypto"; - 104 | createDiffieHellman(Buffer.from([23])).toString(); + 102 | import { createDiffieHellman } from "node:crypto"; + 103 | createDiffieHellman(Buffer.from([23])).toString(); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 105 | /* WebCrypto beyond the secret-key slice: @types/node declares the whole + 104 | /* WebCrypto beyond the secret-key slice: @types/node declares the whole hint: generateKeys(), computeSecret(), getPrime(), getGenerator(), getPublicKey(), getPrivateKey(), setPublicKey(), setPrivateKey() and verifyError are supported -fenced.ts:109:9 - error SC2020: 'crypto.subtle.getPublicKey' is part of the standard library types but has no scriptc lowering yet +fenced.ts:108:9 - error SC2020: 'crypto.subtle.getPublicKey' is part of the standard library types but has no scriptc lowering yet - 108 | async function publicKeyWithWebCrypto(key: import("node:crypto").webcrypto.CryptoKey): Promise { - 109 | await crypto.subtle.getPublicKey(key, ["verify"]); + 107 | async function publicKeyWithWebCrypto(key: import("node:crypto").webcrypto.CryptoKey): Promise { + 108 | await crypto.subtle.getPublicKey(key, ["verify"]); | ^~~~~~~~~~~~~~~~~~~~~~~~~~ - 110 | } + 109 | } hint: the native WebCrypto surface is crypto.subtle's importKey, generateKey and exportKey for HMAC and AES keys (importKey also for PBKDF2 and HKDF keys), encrypt and decrypt with AES-GCM, AES-CBC or AES-CTR, wrapKey and unwrapKey of secret keys with AES-KW or those ciphers, deriveBits and deriveKey with PBKDF2 or HKDF, sign and verify with HMAC, generateKey, importKey, exportKey, sign and verify for ECDSA, Ed25519, RSASSA-PKCS1-v1_5 and RSA-PSS, and digest with SHA-1, SHA-256, SHA-384 or SHA-512, each called directly on crypto.subtle -fenced.ts:114:15 - error SC2020: 'navigator.hardwareConcurrency' is typed by @types/node but has no scriptc lowering yet +fenced.ts:113:15 - error SC2020: 'navigator.hardwareConcurrency' is typed by @types/node but has no scriptc lowering yet - 113 | * compile; the other members fence by name. */ - 114 | const cores = navigator.hardwareConcurrency; + 112 | * compile; the other members fence by name. */ + 113 | const cores = navigator.hardwareConcurrency; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 115 | void cores; + 114 | void cores; hint: of Node's navigator global only typeof navigator and navigator.userAgent compile \ No newline at end of file diff --git a/tests/harness/__snapshots__/split-cjs-require-cycle/main.js.txt b/tests/harness/__snapshots__/split-cjs-require-cycle/main.js.txt new file mode 100644 index 000000000..6c39c35d6 --- /dev/null +++ b/tests/harness/__snapshots__/split-cjs-require-cycle/main.js.txt @@ -0,0 +1,7 @@ +split-cjs-require-cycle/main.js:1:1 - error SC1016: circular imports (split-cjs-require-cycle/main.js → split-cjs-require-cycle/b.js → split-cjs-require-cycle/main.js; the cycle closes through a require() edge: split-cjs-require-cycle/main.js uses its exports at split-cjs-require-cycle/main.js:10 outside the export statements that precede its first require, so a module of the cycle can observe them before they settle) are not supported yet + + 1 | // A split require binding (`var b; b = require("./b.js")`) whose require + | ^ + 2 | // closes a CommonJS cycle that top-level code can observe: b.js reads a.js's + + hint: ES-module cycles of let/const/function bindings compile as-is; rewrite the named construct (a named import instead of a namespace, a const instead of a default-export expression or var, a class declared before the code that can reach it) or break the named edge \ No newline at end of file diff --git a/tests/harness/__snapshots__/split-cjs-require-early/main.js.txt b/tests/harness/__snapshots__/split-cjs-require-early/main.js.txt new file mode 100644 index 000000000..0496cd125 --- /dev/null +++ b/tests/harness/__snapshots__/split-cjs-require-early/main.js.txt @@ -0,0 +1,13 @@ +split-cjs-require-early/main.js:10:7 - error SC1013: require() binding 'lib' assigned below code that can reach it (Node reads undefined before the assignment runs, which is not modeled — move the assignment above the code that can run first) is not supported yet + + 9 | console.log('boot', helper()); + 10 | lib = require('./lib.js'); + | ^~~~~~~~~~~~~~~~~~~ + 11 | + +split-cjs-require-early/main.js:15:12 - error SC1013: require() binding 'wrapped' assigned below code that can reach it (Node reads undefined before the assignment runs, which is not modeled — move the assignment above the code that can run first) is not supported yet + + 14 | console.log('peek', wrapped === undefined); + 15 | wrapped = (require('./lib.js')); + | ^~~~~~~~~~~~~~~~~~~ + 16 | \ No newline at end of file diff --git a/tests/harness/__snapshots__/unions.ts.txt b/tests/harness/__snapshots__/unions.ts.txt index bba468c40..8e801b0fe 100644 --- a/tests/harness/__snapshots__/unions.ts.txt +++ b/tests/harness/__snapshots__/unions.ts.txt @@ -14,16 +14,9 @@ unions.ts:61:22 - error SC1090: string conversions of unions with object arms (n | ^~~~~~ 62 | -unions.ts:69:19 - error SC1090: '== null' / '!= null' on a 'null | string | undefined' value that isn't a plain read (both unit arms need the operand twice — bind it to a const first) is not supported yet +unions.ts:92:10 - error SC1090: reading 'valueOf' on a union-typed value (every arm must be an object/record with a same-typed field 'valueOf'; narrow first: check a discriminant field, or compare with '!== undefined'/'!== null' for unit arms) is not supported yet - 68 | } - 69 | const looseCall = mkNullish() == null; - | ^~~~~~~~~~~~~~~~~~~ - 70 | - -unions.ts:100:10 - error SC1090: reading 'valueOf' on a union-typed value (every arm must be an object/record with a same-typed field 'valueOf'; narrow first: check a discriminant field, or compare with '!== undefined'/'!== null' for unit arms) is not supported yet - - 99 | function chainSubUnion(x: number | string | undefined): number { - 100 | return x?.valueOf === undefined ? 0 : 1; - | ^~~~~~~~~~ - 101 | } \ No newline at end of file + 91 | function chainSubUnion(x: number | string | undefined): number { + 92 | return x?.valueOf === undefined ? 0 : 1; + | ^~~~~~~~~~ + 93 | } \ No newline at end of file diff --git a/tests/harness/ci-test-plan.test.ts b/tests/harness/ci-test-plan.test.ts index 34d61346f..dd77039ca 100644 --- a/tests/harness/ci-test-plan.test.ts +++ b/tests/harness/ci-test-plan.test.ts @@ -11,6 +11,8 @@ import { caseShardedSideFiles, isolatedFiles, leakSuppressions, + memoryHeavyFiles, + sideOwners, testCosts, } from "../../scripts/ci-test-plan.mjs"; import { runCiTestPlan } from "../../scripts/ci-test.mjs"; @@ -40,20 +42,27 @@ test.for([1, 3, 5, 10, 20])( file, ).toHaveLength(everyShard ? count : 1); } - // Each measured file runs on exactly one shard, outside vitest's file shard. + // Each measured or memory-heavy file runs on exactly one shard, outside + // vitest's file shard. const isolated = new Set(isolatedFiles.map(([, file]) => file)); const balanced = plans.flatMap((plan) => plan.side .filter((task) => task.name === "cost-balanced tests") .flatMap((task) => task.args.slice(2)), ); - const measured = Object.keys(testCosts[flavor]).filter((file) => !isolated.has(file)); + const measured = [ + ...new Set([...Object.keys(testCosts[flavor]), ...Object.keys(memoryHeavyFiles)]), + ].filter((file) => !isolated.has(file)); expect(measured.length).toBeGreaterThan(0); expect(balanced.toSorted()).toEqual(measured.toSorted()); for (const plan of plans) { expect(plan.corpus.args).toEqual(["test", ...corpusFiles]); expect(plan.side[0]!.args).toContain(`--shard=${plan.corpus.env.SCRIPTC_TEST_SHARD}`); - for (const file of [...fileExclusions, ...Object.keys(testCosts[flavor])]) + for (const file of [ + ...fileExclusions, + ...Object.keys(testCosts[flavor]), + ...Object.keys(memoryHeavyFiles), + ]) expect(plan.side[0]!.args).toContain(`--exclude=${file}`); const cache = plan.side.find((task) => task.name === "native-cache correctness"); expect(Boolean(cache)).toBe(flavor === "plain"); @@ -103,6 +112,26 @@ test("the side queue balances measured files across the twenty Linux shards", () } }); +test("memory-heavy side files run whole in the cost-balanced task, on shards of their own", () => { + for (const flavor of ["plain", "san"] as const) { + const owners = sideOwners(flavor, 20); + const heavy = Object.keys(memoryHeavyFiles); + const shards = heavy.map((file) => owners.get(file)); + expect(shards.every((shard) => shard !== undefined)).toBe(true); + expect(new Set(shards).size).toBe(Math.min(heavy.length, 20)); + for (const file of heavy) { + const plan = ciTestPlan({ shard: `${owners.get(file)}/20`, flavor }); + const balanced = plan.side.find((task) => task.name === "cost-balanced tests")!; + expect(balanced.args).toContain(file); + // The file-sharded task leaves it out on every shard. + for (let shard = 1; shard <= 20; shard++) + expect(ciTestPlan({ shard: `${shard}/20`, flavor }).side[0]!.args).toContain( + `--exclude=${file}`, + ); + } + } +}); + test.for([1, 2, 4, 8])( "CI overlaps reserved lanes within a budget of %i workers", async (workers) => { @@ -265,7 +294,13 @@ test("pull requests run the full suite on Linux and the darwin suite on macOS", ); expect(coreStep).toBeGreaterThan(-1); expect(coreStep).toBeLessThan(linux.steps.length - 1); - expect(linux.steps.at(-1)!.run).toBe("ulimit -c 0\nnode scripts/ci-test.mjs\n"); + // Linux runs the suites in a memory-capped scope where systemd manages the + // runner, and directly elsewhere. + const linuxRun = linux.steps.at(-1)!.run as string; + expect(linuxRun.startsWith("ulimit -c 0\n")).toBe(true); + expect(linuxRun).toContain("systemd-run --scope --quiet -p MemoryMax=14G -p OOMPolicy=continue"); + expect(linuxRun).toMatch(/-- env PATH="\$PATH" HOME="\$HOME" node scripts\/ci-test\.mjs\n/); + expect(linuxRun.endsWith("fi\nnode scripts/ci-test.mjs\n")).toBe(true); expect(macos.steps.at(-1)!.run).toBe("node scripts/ci-test.mjs"); for (const job of [linux, macos]) expect(job.strategy.matrix.flavor).toEqual(["plain", "san"]); }); diff --git a/tests/harness/corpus-costs/6343-inspect-class-values.ts.json b/tests/harness/corpus-costs/6343-inspect-class-values.ts.json new file mode 100644 index 000000000..fa2590573 --- /dev/null +++ b/tests/harness/corpus-costs/6343-inspect-class-values.ts.json @@ -0,0 +1 @@ +{ "plain": 3700, "san": 4700 } diff --git a/tests/harness/corpus-costs/6344-inspect-function-properties.cjs.json b/tests/harness/corpus-costs/6344-inspect-function-properties.cjs.json new file mode 100644 index 000000000..71bf780f8 --- /dev/null +++ b/tests/harness/corpus-costs/6344-inspect-function-properties.cjs.json @@ -0,0 +1 @@ +{ "plain": 2700, "san": 3500 } diff --git a/tests/harness/corpus-costs/6357-format-o-hidden.ts.json b/tests/harness/corpus-costs/6357-format-o-hidden.ts.json new file mode 100644 index 000000000..f351a5044 --- /dev/null +++ b/tests/harness/corpus-costs/6357-format-o-hidden.ts.json @@ -0,0 +1 @@ +{ "plain": 2300, "san": 2100 } diff --git a/tests/harness/corpus-costs/6358-format-o-hidden-js.cjs.json b/tests/harness/corpus-costs/6358-format-o-hidden-js.cjs.json new file mode 100644 index 000000000..1f8ff72b2 --- /dev/null +++ b/tests/harness/corpus-costs/6358-format-o-hidden-js.cjs.json @@ -0,0 +1 @@ +{ "plain": 2100, "san": 2000 } diff --git a/tests/harness/corpus-costs/6935-fs-url-paths-ordered.ts.json b/tests/harness/corpus-costs/6935-fs-url-paths-ordered.ts.json new file mode 100644 index 000000000..f2dfcb1a1 --- /dev/null +++ b/tests/harness/corpus-costs/6935-fs-url-paths-ordered.ts.json @@ -0,0 +1 @@ +{ "plain": 3746, "san": 5148 } diff --git a/tests/harness/corpus-costs/7012-dictionary-views-keep-objects.ts.json b/tests/harness/corpus-costs/7012-dictionary-views-keep-objects.ts.json new file mode 100644 index 000000000..dcf40a9fa --- /dev/null +++ b/tests/harness/corpus-costs/7012-dictionary-views-keep-objects.ts.json @@ -0,0 +1 @@ +{ "plain": 2368, "san": 3286 } diff --git a/tests/harness/corpus-costs/7013-dictionary-view-parameter.ts.json b/tests/harness/corpus-costs/7013-dictionary-view-parameter.ts.json new file mode 100644 index 000000000..911881768 --- /dev/null +++ b/tests/harness/corpus-costs/7013-dictionary-view-parameter.ts.json @@ -0,0 +1 @@ +{ "plain": 1466, "san": 2392 } diff --git a/tests/harness/corpus-costs/7189-non-null-assertion-nullish-destination.ts.json b/tests/harness/corpus-costs/7189-non-null-assertion-nullish-destination.ts.json new file mode 100644 index 000000000..7473d65aa --- /dev/null +++ b/tests/harness/corpus-costs/7189-non-null-assertion-nullish-destination.ts.json @@ -0,0 +1 @@ +{ "plain": 2653, "san": 3208 } diff --git a/tests/harness/corpus-costs/7392-non-null-operands.ts.json b/tests/harness/corpus-costs/7392-non-null-operands.ts.json new file mode 100644 index 000000000..a591cc420 --- /dev/null +++ b/tests/harness/corpus-costs/7392-non-null-operands.ts.json @@ -0,0 +1 @@ +{ "plain": 4200, "san": 4800 } diff --git a/tests/harness/corpus-costs/7394-non-null-typed-array-reads.ts.json b/tests/harness/corpus-costs/7394-non-null-typed-array-reads.ts.json new file mode 100644 index 000000000..ad10beaaa --- /dev/null +++ b/tests/harness/corpus-costs/7394-non-null-typed-array-reads.ts.json @@ -0,0 +1 @@ +{ "plain": 4300, "san": 3900 } diff --git a/tests/harness/corpus-costs/7453-untyped-overload-results.cjs.json b/tests/harness/corpus-costs/7453-untyped-overload-results.cjs.json new file mode 100644 index 000000000..46a1181bd --- /dev/null +++ b/tests/harness/corpus-costs/7453-untyped-overload-results.cjs.json @@ -0,0 +1 @@ +{ "plain": 2991, "san": 4866 } diff --git a/tests/harness/corpus-costs/7624-key-order-boxed-callback-records/main.ts.json b/tests/harness/corpus-costs/7624-key-order-boxed-callback-records/main.ts.json new file mode 100644 index 000000000..fb3015dce --- /dev/null +++ b/tests/harness/corpus-costs/7624-key-order-boxed-callback-records/main.ts.json @@ -0,0 +1 @@ +{ "plain": 6931, "san": 8003 } diff --git a/tests/harness/corpus-costs/7680-typed-array-search.ts.json b/tests/harness/corpus-costs/7680-typed-array-search.ts.json new file mode 100644 index 000000000..37f8b6e89 --- /dev/null +++ b/tests/harness/corpus-costs/7680-typed-array-search.ts.json @@ -0,0 +1 @@ +{ "plain": 2204, "san": 3060 } diff --git a/tests/harness/corpus-costs/7681-typed-array-search-dynamic.mjs.json b/tests/harness/corpus-costs/7681-typed-array-search-dynamic.mjs.json new file mode 100644 index 000000000..b6fcd5eff --- /dev/null +++ b/tests/harness/corpus-costs/7681-typed-array-search-dynamic.mjs.json @@ -0,0 +1 @@ +{ "plain": 1649, "san": 958 } diff --git a/tests/harness/corpus-costs/7682-constructor-function-globals.js.json b/tests/harness/corpus-costs/7682-constructor-function-globals.js.json new file mode 100644 index 000000000..90fcede92 --- /dev/null +++ b/tests/harness/corpus-costs/7682-constructor-function-globals.js.json @@ -0,0 +1 @@ +{ "plain": 1623, "san": 962 } diff --git a/tests/harness/corpus-costs/7714-zlib-brotli-compress.cjs.json b/tests/harness/corpus-costs/7714-zlib-brotli-compress.cjs.json new file mode 100644 index 000000000..7c5c28b59 --- /dev/null +++ b/tests/harness/corpus-costs/7714-zlib-brotli-compress.cjs.json @@ -0,0 +1 @@ +{ "plain": 5362, "san": 120966 } diff --git a/tests/harness/corpus-costs/7715-zlib-brotli-decompress.cjs.json b/tests/harness/corpus-costs/7715-zlib-brotli-decompress.cjs.json new file mode 100644 index 000000000..de8ec5e7a --- /dev/null +++ b/tests/harness/corpus-costs/7715-zlib-brotli-decompress.cjs.json @@ -0,0 +1 @@ +{ "plain": 4974, "san": 112620 } diff --git a/tests/harness/corpus-costs/7716-zlib-brotli.ts.json b/tests/harness/corpus-costs/7716-zlib-brotli.ts.json new file mode 100644 index 000000000..a4b393de1 --- /dev/null +++ b/tests/harness/corpus-costs/7716-zlib-brotli.ts.json @@ -0,0 +1 @@ +{ "plain": 3930, "san": 108068 } diff --git a/tests/harness/corpus-costs/7745-typed-array-unions.ts.json b/tests/harness/corpus-costs/7745-typed-array-unions.ts.json new file mode 100644 index 000000000..ee546c4fd --- /dev/null +++ b/tests/harness/corpus-costs/7745-typed-array-unions.ts.json @@ -0,0 +1 @@ +{ "plain": 3450, "san": 4000 } diff --git a/tests/harness/corpus-costs/7747-typed-array-class-values.ts.json b/tests/harness/corpus-costs/7747-typed-array-class-values.ts.json new file mode 100644 index 000000000..89e0d92e7 --- /dev/null +++ b/tests/harness/corpus-costs/7747-typed-array-class-values.ts.json @@ -0,0 +1 @@ +{ "plain": 2400, "san": 2350 } diff --git a/tests/harness/corpus-costs/7748-typed-array-number-array-unions.ts.json b/tests/harness/corpus-costs/7748-typed-array-number-array-unions.ts.json new file mode 100644 index 000000000..89fb8ddd2 --- /dev/null +++ b/tests/harness/corpus-costs/7748-typed-array-number-array-unions.ts.json @@ -0,0 +1 @@ +{ "plain": 2550, "san": 2300 } diff --git a/tests/harness/corpus-costs/7749-typed-array-element-searches.ts.json b/tests/harness/corpus-costs/7749-typed-array-element-searches.ts.json new file mode 100644 index 000000000..7d76a0583 --- /dev/null +++ b/tests/harness/corpus-costs/7749-typed-array-element-searches.ts.json @@ -0,0 +1 @@ +{ "plain": 2650, "san": 2850 } diff --git a/tests/harness/corpus-costs/7750-typed-array-union-inspect.ts.json b/tests/harness/corpus-costs/7750-typed-array-union-inspect.ts.json new file mode 100644 index 000000000..c0aef3bb7 --- /dev/null +++ b/tests/harness/corpus-costs/7750-typed-array-union-inspect.ts.json @@ -0,0 +1 @@ +{ "plain": 2700, "san": 3900 } diff --git a/tests/harness/corpus-costs/7752-typed-array-dynamic-methods.js.json b/tests/harness/corpus-costs/7752-typed-array-dynamic-methods.js.json new file mode 100644 index 000000000..a3c2e4739 --- /dev/null +++ b/tests/harness/corpus-costs/7752-typed-array-dynamic-methods.js.json @@ -0,0 +1 @@ +{ "plain": 4800, "san": 5400 } diff --git a/tests/harness/corpus-costs/7796-boxed-subclass-identity.js.json b/tests/harness/corpus-costs/7796-boxed-subclass-identity.js.json new file mode 100644 index 000000000..3dfdb2b6d --- /dev/null +++ b/tests/harness/corpus-costs/7796-boxed-subclass-identity.js.json @@ -0,0 +1 @@ +{ "plain": 4600, "san": 5500 } diff --git a/tests/harness/corpus-costs/7982-integer-view-compares.ts.json b/tests/harness/corpus-costs/7982-integer-view-compares.ts.json new file mode 100644 index 000000000..39d9e2b8a --- /dev/null +++ b/tests/harness/corpus-costs/7982-integer-view-compares.ts.json @@ -0,0 +1 @@ +{ "plain": 3700, "san": 4600 } diff --git a/tests/harness/corpus-costs/7991-unknown-class-union-casts.ts.json b/tests/harness/corpus-costs/7991-unknown-class-union-casts.ts.json new file mode 100644 index 000000000..263ca9783 --- /dev/null +++ b/tests/harness/corpus-costs/7991-unknown-class-union-casts.ts.json @@ -0,0 +1 @@ +{ "plain": 4400 } diff --git a/tests/harness/corpus-costs/8110-builtin-prototype-own-members.js.json b/tests/harness/corpus-costs/8110-builtin-prototype-own-members.js.json new file mode 100644 index 000000000..5c4dabee9 --- /dev/null +++ b/tests/harness/corpus-costs/8110-builtin-prototype-own-members.js.json @@ -0,0 +1 @@ +{ "plain": 2900, "san": 41100 } diff --git a/tests/harness/corpus-costs/8111-plain-object-check-unknown.ts.json b/tests/harness/corpus-costs/8111-plain-object-check-unknown.ts.json new file mode 100644 index 000000000..c40ea383d --- /dev/null +++ b/tests/harness/corpus-costs/8111-plain-object-check-unknown.ts.json @@ -0,0 +1 @@ +{ "plain": 1600, "san": 7700 } diff --git a/tests/harness/corpus-costs/8112-error-factory-own-key-order.js.json b/tests/harness/corpus-costs/8112-error-factory-own-key-order.js.json new file mode 100644 index 000000000..9013dc548 --- /dev/null +++ b/tests/harness/corpus-costs/8112-error-factory-own-key-order.js.json @@ -0,0 +1 @@ +{ "plain": 2200, "san": 10300 } diff --git a/tests/harness/corpus-costs/8113-error-class-field-before-name.js.json b/tests/harness/corpus-costs/8113-error-class-field-before-name.js.json new file mode 100644 index 000000000..29164fca3 --- /dev/null +++ b/tests/harness/corpus-costs/8113-error-class-field-before-name.js.json @@ -0,0 +1 @@ +{ "plain": 1900, "san": 9700 } diff --git a/tests/harness/corpus-costs/8115-error-prototype-identity.js.json b/tests/harness/corpus-costs/8115-error-prototype-identity.js.json new file mode 100644 index 000000000..57bb2b280 --- /dev/null +++ b/tests/harness/corpus-costs/8115-error-prototype-identity.js.json @@ -0,0 +1 @@ +{ "plain": 5600, "san": 5100 } diff --git a/tests/harness/corpus-costs/8129-brotli-long-param-name.cjs.json b/tests/harness/corpus-costs/8129-brotli-long-param-name.cjs.json new file mode 100644 index 000000000..3680ecbea --- /dev/null +++ b/tests/harness/corpus-costs/8129-brotli-long-param-name.cjs.json @@ -0,0 +1 @@ +{ "plain": 7006, "san": 14012 } diff --git a/tests/harness/corpus-costs/8160-assert-expected-from-fields.cjs.json b/tests/harness/corpus-costs/8160-assert-expected-from-fields.cjs.json new file mode 100644 index 000000000..cdfeabea9 --- /dev/null +++ b/tests/harness/corpus-costs/8160-assert-expected-from-fields.cjs.json @@ -0,0 +1 @@ +{ "plain": 2656, "san": 5234 } diff --git a/tests/harness/corpus-costs/8180-pow2-quotients.ts.json b/tests/harness/corpus-costs/8180-pow2-quotients.ts.json new file mode 100644 index 000000000..63f95b985 --- /dev/null +++ b/tests/harness/corpus-costs/8180-pow2-quotients.ts.json @@ -0,0 +1 @@ +{ "plain": 2301, "san": 3300 } diff --git a/tests/harness/corpus-costs/split-cjs-require-binding/main.cjs.json b/tests/harness/corpus-costs/split-cjs-require-binding/main.cjs.json new file mode 100644 index 000000000..9d570f700 --- /dev/null +++ b/tests/harness/corpus-costs/split-cjs-require-binding/main.cjs.json @@ -0,0 +1 @@ +{ "plain": 1500, "san": 12000 } diff --git a/tests/harness/corpus-costs/split-cjs-require-cycle/main.cjs.json b/tests/harness/corpus-costs/split-cjs-require-cycle/main.cjs.json new file mode 100644 index 000000000..9619c105e --- /dev/null +++ b/tests/harness/corpus-costs/split-cjs-require-cycle/main.cjs.json @@ -0,0 +1 @@ +{ "plain": 2700, "san": 3200 } diff --git a/tests/harness/corpus-costs/typed-array-masked-index-stores.ts.json b/tests/harness/corpus-costs/typed-array-masked-index-stores.ts.json new file mode 100644 index 000000000..3e45ee566 --- /dev/null +++ b/tests/harness/corpus-costs/typed-array-masked-index-stores.ts.json @@ -0,0 +1 @@ +{ "plain": 2791, "san": 3186 } diff --git a/tests/harness/dyncheck.test.ts b/tests/harness/dyncheck.test.ts index 6a2d4dc61..15068776a 100644 --- a/tests/harness/dyncheck.test.ts +++ b/tests/harness/dyncheck.test.ts @@ -1278,4 +1278,193 @@ console.log("done", caught); expect(r.exitCode).toBe(0); expect(r.stdout).toBe("done 100\n"); }); + + test("an inspection refusal throws before console.log writes", async () => { + // A promise reached through `unknown` has no dynamic rendering; the + // refusal must stop the call, not print a partial line and continue. + const r = await compileAndRun( + "inspect-refusal-unwind", + `import { inspect } from "node:util"; +const p: unknown = Promise.resolve(3); +function attempt(label: string, f: () => void): void { + try { + f(); + console.log(label, "returned"); + } catch (e) { + console.log(label, (e as Error).message); + } +} +attempt("log", () => console.log("x", p)); +attempt("inspect", () => console.log(inspect(p).length)); +attempt("record", () => console.log({ a: p })); +attempt("array", () => console.log([p])); +console.log("before"); +console.log(p); +console.log("after"); +`, + ); + const refusal = "util.inspect of a promise value is not supported yet"; + expect(r.exitCode).toBe(1); + expect(r.stdout).toBe( + ["log", "inspect", "record", "array"].map((l) => `${l} ${refusal}\n`).join("") + "before\n", + ); + expect(r.stderr).toContain(`Uncaught Error: ${refusal}`); + }); + + test("a refusal in a record's kept source properties closes the inspector's frames", async () => { + // A record converted from an object with undeclared properties renders + // them through its checked view; a refusal there, inside an enclosing + // record or array, must not leave that render's frames open. + const r = await compileAndRun( + "inspect-refusal-kept-source", + `import { inspect } from "node:util"; +type P = { a: number }; +const src = JSON.parse('{"a":1}'); +src.p = Promise.resolve(3); +const r: P = src; +function attempt(label: string, f: () => void): void { + try { + f(); + console.log(label, "returned"); + } catch (e) { + console.log(label, (e as Error).message); + } +} +attempt("record", () => console.log(inspect({ outer: r, n: [1, 2] }))); +console.log(inspect({ b: [1, { c: 2 }], long: "x".repeat(70) })); +attempt("array", () => console.log(inspect([r, r]))); +console.log([3, 4], { d: 5 }); +`, + ); + const refusal = "util.inspect of a promise value is not supported yet"; + expect(r.exitCode).toBe(0); + expect(r.stdout).toBe( + `record ${refusal}\n` + + `{\n b: [ 1, { c: 2 } ],\n long: '${"x".repeat(70)}'\n}\n` + + `array ${refusal}\n` + + "[ 3, 4 ] { d: 5 }\n", + ); + }); + + test("accessors reached through unknown render as Node's accessor tags", async () => { + const r = await compileAndRun( + "inspect-accessor-tags", + `import { format } from "node:util"; +const o: unknown = JSON.parse('{"x":1}'); +Object.defineProperty(o, "g", { get: () => 2, enumerable: true }); +Object.defineProperty(o, "h", { get: () => 3, enumerable: false }); +Object.defineProperty(o, "gs", { get: () => 4, set: (_v: number) => {}, enumerable: false }); +Object.defineProperty(o, "s", { set: (_v: number) => {}, enumerable: true }); +console.log(o); +console.log(format("%o", o)); +`, + ); + expect(r.exitCode).toBe(0); + expect(r.stdout).toBe( + [ + "{ x: 1, g: [Getter], s: [Setter] }", + "{", + " x: 1,", + " g: [Getter],", + " [h]: [Getter],", + " [gs]: [Getter/Setter],", + " s: [Setter]", + "}", + "", + ].join("\n"), + ); + }); + + test("a refused inspection leaves later renders at the default layout", async () => { + // The refusal's Error skips the call site's layout restore and the + // render's own exits; later renders must not keep the custom layout, + // the indentation, showHidden or open frames of the abandoned one. + const r = await compileAndRun( + "inspect-refusal-state", + `import { format, inspect } from "node:util"; +const p: unknown = Promise.resolve(1); +const rec: unknown = { a: [1], b: p }; +try { + inspect({ a: [1, 2, 3, 4, 5, 6, 7, 8], b: p }, { breakLength: 20 }); +} catch {} +try { + format("%o", rec); +} catch {} +const long: unknown = JSON.parse(JSON.stringify(Array.from({ length: 12 }, (_, i) => "item" + i))); +console.log(long); +console.log(format("%O", [1])); +`, + ); + expect(r.exitCode).toBe(0); + expect(r.stdout).toBe( + [ + "[", + " 'item0', 'item1',", + " 'item2', 'item3',", + " 'item4', 'item5',", + " 'item6', 'item7',", + " 'item8', 'item9',", + " 'item10', 'item11'", + "]", + "[ 1 ]", + "", + ].join("\n"), + ); + }); + + test("inspecting a compiled class with static fields through unknown refuses", async () => { + // Node prints `[class S] { count: 3 }`; the class object does not + // carry compiled static fields, so the inspector refuses rather than + // print `[class S]`. A class without static fields still prints. + const r = await compileAndRun( + "inspect-class-statics", + `class Plain {} +class S extends Plain { + static count = 3; +} +const plain: unknown = Plain; +const s: unknown = S; +console.log(plain); +try { + console.log(s); +} catch (e) { + console.log((e as Error).message); +} +`, + ); + expect(r.exitCode).toBe(0); + expect(r.stdout).toBe( + "[class Plain]\nutil.inspect of a class with static fields through unknown is not supported yet\n", + ); + }); + + test("%o refuses the dynamic kinds whose hidden entries have no rendering", async () => { + // Node's showHidden adds a function's length/name/prototype, an + // error's stack and a typed array's byte fields; %o throws the 'not + // supported yet' Error for them instead of printing without them. + const r = await compileAndRun( + "format-o-hidden-refusals", + `import { format } from "node:util"; +function f(): void {} +const values: [string, unknown][] = [["fn", f], ["err", new Error("e")], ["u8", new Uint8Array(1)], ["arr", [1]]]; +for (const [label, value] of values) { + try { + console.log(label, format("%o", value)); + } catch (e) { + console.log(label, (e as Error).message); + } +} +`, + ); + expect(r.exitCode).toBe(0); + expect(r.stdout).toBe( + [ + "fn util.format %o of function values is not supported yet", + "err util.format %o of Error values is not supported yet", + "u8 util.format %o of typed array values is not supported yet", + "arr [ 1, [length]: 1 ]", + "", + ].join("\n"), + ); + }); }); diff --git a/tests/harness/errors.test.ts b/tests/harness/errors.test.ts index 20231a94e..cd836eea2 100644 --- a/tests/harness/errors.test.ts +++ b/tests/harness/errors.test.ts @@ -325,6 +325,35 @@ console.log(cells.join(",")); ); }); + test("a split require closing a CommonJS cycle keeps the const form's SC1016", async () => { + // Node answers the closing require with the dependency's partial exports + // ({ fromA: 1 } at this point), which the static export model cannot + // represent. Preflight treats the split assignment like `const a = + // require("./a.cjs")`, so the cycle keeps that form's SC1016 instead of + // reading uninitialized export storage. A cycle whose reads are all deferred + // compiles (tests/corpus/split-cjs-require-cycle). + const r = compileAndRun( + "split-require-cycle", + `require("./a.cjs"); +`, + "cjs", + { + "a.cjs": `exports.fromA = 1; +const b = require("./b.cjs"); +exports.fromB = b.fromB; +`, + "b.cjs": `exports.fromB = 2; +var a; +a = require("./a.cjs"); +console.log(a.fromA, a.fromB); +`, + }, + ); + await expect(r).rejects.toThrow( + /SC1016: circular imports \(.*a\.cjs → .*b\.cjs → .*a\.cjs; the cycle closes through a require\(\) edge/, + ); + }); + test("an EFFECTFUL surplus argument is a named deferred fence (JS lane)", async () => { // Effect-free surplus args drop at compile time, JS-exact (corpus // 1760 — the test-string-decoder writeSequences shape). An effectful diff --git a/tests/harness/event-loop-cases.ts b/tests/harness/event-loop-cases.ts index 40bc7988d..50a7d2b85 100644 --- a/tests/harness/event-loop-cases.ts +++ b/tests/harness/event-loop-cases.ts @@ -34,6 +34,66 @@ export const eventLoopCases: EventLoopCase[] = [ fixture: "stdio-paused-exit.mjs", script: { writes: [], end: false }, }, + { + title: "stdio values: 'readable' drains with read(), then fires once more at EOF", + fixture: "stdio-readable.mjs", + script: { + writes: [ + { delayMs: 0, data: "alpha " }, + { delayMs: 60, data: "beta\n" }, + ], + end: true, + }, + }, + { + title: "stdio values: 'readable' with read(size) holds a partial tail until EOF", + fixture: "stdio-readable-size.mjs", + script: { writes: [{ delayMs: 0, data: "abcdefghij" }], end: true }, + }, + { + title: "stdio values: input a once('readable') listener leaves stays buffered for 'data'", + fixture: "stdio-readable-once-rest.mjs", + script: { writes: [{ delayMs: 0, data: "abcdefgh" }], end: true }, + }, + { + title: "stdio values: 'readable' with a read(size) above the read-ahead mark", + fixture: "stdio-readable-large-size.mjs", + script: { + writes: [ + { delayMs: 0, data: "a".repeat(70000) }, + { delayMs: 30, data: "b".repeat(70000) }, + { delayMs: 30, data: "c".repeat(60000) }, + ], + end: true, + }, + }, + { + title: "stdio values: 'readable' with 'data' and resume() holds input at the read-ahead mark", + fixture: "stdio-readable-backpressure.mjs", + script: { + writes: Array.from({ length: 16 }, (_, i) => ({ + delayMs: i === 0 ? 0 : 5, + data: String.fromCharCode(97 + i).repeat(65536), + })), + end: true, + }, + }, + { + title: "stdio values: 'readable' on an immediately ended pipe", + fixture: "stdio-readable.mjs", + script: { writes: [], end: true }, + }, + { + title: "for-await: process.stdin yields Buffers", + fixture: "stdin-for-await-buffers.mjs", + script: { + writes: [ + { delayMs: 0, data: "#one\nabcd\n" }, + { delayMs: 40, data: "#two\nefgh\n" }, + ], + end: true, + }, + }, { title: "read-all: one instant write, then EOF", fixture: "stdin-read-all.ts", diff --git a/tests/harness/library-mode.test.ts b/tests/harness/library-mode.test.ts index 47b77f0fd..2b0ac2c89 100644 --- a/tests/harness/library-mode.test.ts +++ b/tests/harness/library-mode.test.ts @@ -1075,13 +1075,13 @@ describe.each(EMISSIONS)("K14: determinism fences, %s emission", (emission) => { test("a manifest-id-keyed teachings entry attaches to that surface's own refusal", async () => { const diags = await refusal( - `import { brotliCompressSync } from "node:zlib";\nexport function f(): number { return brotliCompressSync("data").length; }\n`, + `import { createRequire } from "node:module";\nexport function f(): number { return createRequire("/x") === undefined ? 0 : 1; }\n`, { exports: [{ export: "f", symbol: "kx_f", params: [], returns: "f64" }], determinism: { teachings: { - "node-builtin.zlib.brotliCompressSync": - "compression runs in the host; request it as an effect", + "node-builtin.module.createRequire": + "module state is the host's; request it as an effect", }, }, }, @@ -1090,20 +1090,20 @@ describe.each(EMISSIONS)("K14: determinism fences, %s emission", (emission) => { // The surface's own code, not a fence code: the id key attaches text // to the refusal that already fires. expect(diags[0]!.code).toBe("SC2020"); - expect(diags[0]!.message).toContain("zlib.brotliCompressSync"); + expect(diags[0]!.message).toContain("module.createRequire"); expect(diags[0]!.note).toBe( - "from the 'refusal-fixture' profile: compression runs in the host; request it as an effect", + "from the 'refusal-fixture' profile: module state is the host's; request it as an effect", ); }); test("fencing a surface the static tier refuses anyway changes only the message", async () => { const diags = await refusal( - `import { brotliCompressSync } from "node:zlib";\nexport function f(): number { return brotliCompressSync("data").length; }\n`, + `import { createRequire } from "node:module";\nexport function f(): number { return createRequire("/x") === undefined ? 0 : 1; }\n`, { exports: [{ export: "f", symbol: "kx_f", params: [], returns: "f64" }], determinism: { fences: [ - { id: "node-builtin.zlib.brotliCompressSync", teaching: "compression is host work" }, + { id: "node-builtin.module.createRequire", teaching: "module state is host work" }, ], }, }, @@ -1112,6 +1112,6 @@ describe.each(EMISSIONS)("K14: determinism fences, %s emission", (emission) => { // The existing refusal's code survives — the fence never re-codes a // surface that already refuses; its teaching rides as the note. expect(diags[0]!.code).toBe("SC2020"); - expect(diags[0]!.note).toBe("from the 'refusal-fixture' profile: compression is host work"); + expect(diags[0]!.note).toBe("from the 'refusal-fixture' profile: module state is host work"); }); }); diff --git a/tests/harness/npm.test.ts b/tests/harness/npm.test.ts index ff9e09d61..27b27b8e3 100644 --- a/tests/harness/npm.test.ts +++ b/tests/harness/npm.test.ts @@ -114,14 +114,17 @@ const cases = shardSelect(npmCases(fixturesRoot), (c) => c.name); /** Per-case timeouts past the default 120 s: the undici cases compile the * built-in undici implementation's module graph, the zod 3 cases (zod3, * zod3-adoption, zod3-boundary, zod3-infer) compile zod 3's 3,700-line - * types module, and the zod 4 cases (zod4-boundary, hono-zod-validator) + * types module, and the zod 4 cases (zod4-boundary, zod4-record, + * hono-zod-validator, hono-zod-default-hook) * compile zod 4's core, classic API and locales. A sanitized build of any * of them takes minutes on a CI runner. */ const TIMEOUTS: Record = { + "hono-zod-default-hook": 900_000, "hono-zod-validator": 900_000, undici5: 600_000, undici7: 600_000, "zod4-boundary": 900_000, + "zod4-record": 900_000, zod3: 600_000, "zod3-adoption": 600_000, "zod3-boundary": 600_000, diff --git a/tests/harness/project-config.test.ts b/tests/harness/project-config.test.ts index ea5ddd51f..e2ab35c71 100644 --- a/tests/harness/project-config.test.ts +++ b/tests/harness/project-config.test.ts @@ -802,20 +802,17 @@ test("node-types: fs functions take URL paths under @types/node's PathLike", asy expect(stdout).toBe("hello 5 5\n"); }); -test("node-types: existsSync and fs.promises URL paths remain named fences", async () => { - const dir = outDirFor("node-fs-url-path-fences"); - const result = await compile(join(nodeTypesDir, "fs-url-path-fences.ts"), { - outPath: join(dir, "fs-url-path-fences"), +test("node-types: existsSync and fs.promises answer false or reject for unconvertible URLs", async () => { + const dir = outDirFor("node-fs-url-fallible"); + const result = await compile(join(nodeTypesDir, "fs-url-fallible.ts"), { + outPath: join(dir, "fs-url-fallible"), outDir: dir, sanitize, }); - expect(result.ok).toBe(false); - if (result.ok) return; - expect(result.diagnostics.map((diagnostic) => [diagnostic.code, diagnostic.message])).toEqual([ - ["SC2020", expect.stringContaining("'existsSync with a URL path'")], - ["SC2020", expect.stringContaining("'fs.promises.readFile with a URL path'")], - ["SC2020", expect.stringContaining("'fs.promises.stat with a URL path'")], - ]); + expect(result.ok, !result.ok ? JSON.stringify(result.diagnostics, null, 2) : "").toBe(true); + if (!result.ok) return; + const { stdout } = await execFileAsync(result.binaryPath); + expect(stdout).toBe("true false\nhi\nERR_INVALID_FILE_URL_HOST\n"); }); test("node-types: path and os lower statically under @types/node's shapes", async () => { diff --git a/tests/harness/self-hosting-llvm-emitter.test.ts b/tests/harness/self-hosting-llvm-emitter.test.ts index cb9cd69c4..a81bac16c 100644 --- a/tests/harness/self-hosting-llvm-emitter.test.ts +++ b/tests/harness/self-hosting-llvm-emitter.test.ts @@ -92,6 +92,7 @@ const programs = [ "local-union-storage.ts", "class-callback-storage.ts", "byte-record-windows.ts", + "typed-array-masked-index-stores.ts", "constant-callback-dispatch.ts", "constant-number-remainders.ts", "numeric-call-specialization.ts", @@ -99,6 +100,10 @@ const programs = [ "native-worker-roots/main.ts", "native-worker-shared-views.ts", ]; +// Debug info turns the emitter's loop optimizations off. These programs are +// emitted without it, so the compiled emitter runs its loop analyses on them +// (typed-array loop versioning, which caches null index shapes). +const withoutDebugInfo = new Set(["typed-array-masked-index-stores.ts"]); for (const backend of ["llvm"] as const) { test( @@ -227,10 +232,12 @@ for (const backend of ["llvm"] as const) { if (!lowered.ok) throw new Error(`${source}: ${lowered.diagnostics.map((d) => d.message).join("\n")}`); const mod = deserializeModule(readFileSync(irPath, "utf8")); - const request: LlvmEmitterRequest = llvmEmitterRequest({ - debug: true, - sources: [{ file: sourcePath, text: readFileSync(sourcePath, "utf8") }], - }); + const request: LlvmEmitterRequest = withoutDebugInfo.has(source) + ? llvmEmitterRequest() + : llvmEmitterRequest({ + debug: true, + sources: [{ file: sourcePath, text: readFileSync(sourcePath, "utf8") }], + }); const text = await emit(mod, source, request); const llvmPath = join(dir, "program.ll"); const outPath = executable("program");