Showing preview only (1,471K chars total). Download the full file or copy to clipboard to get everything.
Repository: nfroidure/ttf2woff2
Branch: main
Commit: cf7ca96079bd
Files: 87
Total size: 1.4 MB
Directory structure:
gitextract_ur_7czr5/
├── .editorconfig
├── .gitattributes
├── .github/
│ ├── CODE_OF_CONDUCT.md
│ ├── CONTRIBUTING
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE
│ ├── PULL_REQUEST_TEMPLATE
│ └── workflows/
│ └── test.yml
├── .gitignore
├── .vscode/
│ ├── extensions.json
│ └── settings.json
├── CHANGELOG.md
├── LICENSE
├── README.md
├── bin/
│ └── ttf2woff2.js
├── binding.gyp
├── csrc/
│ ├── addon.cc
│ ├── enc/
│ │ ├── backward_references.cc
│ │ ├── backward_references.h
│ │ ├── bit_cost.h
│ │ ├── block_splitter.cc
│ │ ├── block_splitter.h
│ │ ├── brotli_bit_stream.cc
│ │ ├── brotli_bit_stream.h
│ │ ├── cluster.h
│ │ ├── command.h
│ │ ├── context.h
│ │ ├── dictionary.h
│ │ ├── dictionary_hash.h
│ │ ├── encode.cc
│ │ ├── encode.h
│ │ ├── encode_parallel.cc
│ │ ├── encode_parallel.h
│ │ ├── entropy_encode.cc
│ │ ├── entropy_encode.h
│ │ ├── fast_log.h
│ │ ├── find_match_length.h
│ │ ├── hash.h
│ │ ├── histogram.cc
│ │ ├── histogram.h
│ │ ├── literal_cost.cc
│ │ ├── literal_cost.h
│ │ ├── metablock.cc
│ │ ├── metablock.h
│ │ ├── port.h
│ │ ├── prefix.h
│ │ ├── ringbuffer.h
│ │ ├── static_dict.h
│ │ ├── streams.cc
│ │ ├── streams.h
│ │ ├── streams.h.gch
│ │ ├── transform.h
│ │ └── write_bits.h
│ ├── fallback.cc
│ └── woff2/
│ ├── buffer.h
│ ├── font.cc
│ ├── font.h
│ ├── glyph.cc
│ ├── glyph.h
│ ├── normalize.cc
│ ├── normalize.h
│ ├── port.h
│ ├── round.h
│ ├── store_bytes.h
│ ├── table_tags.cc
│ ├── table_tags.h
│ ├── transform.cc
│ ├── transform.h
│ ├── variable_length.cc
│ ├── variable_length.h
│ ├── woff2_common.cc
│ ├── woff2_common.h
│ ├── woff2_dec.cc
│ ├── woff2_dec.h
│ ├── woff2_enc.cc
│ └── woff2_enc.h
├── eslint.config.js
├── install/
│ └── try-build.js
├── jssrc/
│ ├── index.js
│ ├── post.js
│ ├── ttf2woff2.cjs
│ └── ttf2woff2.wasm
├── package.json
├── src/
│ ├── cli.test.ts
│ ├── index.ts
│ └── tests.test.ts
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# This file is automatically generated by a `metapak`
# module. Do not change it elsewhere, changes would
# be overridden.
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
# 2 space indentation
[*.{js,css}]
charset = utf-8
indent_style = space
trim_trailing_whitespace = true
indent_size = 2
================================================
FILE: .gitattributes
================================================
# Enforce Unix newlines
* text=auto eol=lf
================================================
FILE: .github/CODE_OF_CONDUCT.md
================================================
# Code of Conduct
Be kind, except if I behave like an asshole, if so, tell me by linking to this
file.
I try hard to document and automate things so that you cannot create noises
without really willing to do so.
This is why I'll just delete issues/comments making be sad.
================================================
FILE: .github/CONTRIBUTING
================================================
Contributing to this project requires you to be
a gentleman.
By contributing you must agree with publishing your
changes into the same license that apply to the current code.
You will find the license in the LICENSE file at
the root of this repository.
================================================
FILE: .github/FUNDING.yml
================================================
github: [nfroidure]
================================================
FILE: .github/ISSUE_TEMPLATE
================================================
## Issue
<!--
Thanks for reporting an issue.
Before doing so, there are a few checks to do in
order to optimize its resolution. Just fill in the
following template.
Beware that you also can create a pull request
if you know how to solve the issue.
Finally scroll down if you are asking for a new feature ;)
-->
I'm a gentledev I:
- [ ] fully read the README recently
- [ ] searched for existing issues
- [ ] checked I'm up to date with the latest version of the project
### Expected behavior
### Actual behavior
### Steps to reproduce the behavior
### Debugging informations
- `node -v` result:
```
<paste here>
```
- `npm -v` result:
```
<paste here>
```
If the result is lower than 20.11.1, there is
poor chances I even have a look to it. Please,
use the last [NodeJS LTS version](https://nodejs.org/en/).
## Feature request
<!--
If you think a feature need to be added, your suggestions
are welcome. Beware though that:
- I try to keep my modules simple so please ensure the requested
feature is really related to this module. If not, you may
instead create a module that augment/work with this one,
- I am not your employee so keep calm and be aware that your
request may stay incomplete for ever. Nothing impeach you
to implement the feature and get it merged though.
-->
### Feature description
### Use cases
- [ ] I will/did implement the feature
================================================
FILE: .github/PULL_REQUEST_TEMPLATE
================================================
<!--
Thanks for improving this project!
Before doing so, there are a few checks to do in
order to get your PR merged asap. Just fill in the
following template.
-->
Fixes #
### Proposed changes
-
-
<!-- Check the boxes with a `x` like so `[x]` -->
### Code quality
- [ ] I made some tests for my changes
- [ ] I added my name in the
[contributors](https://docs.npmjs.com/files/package.json#people-fields-author-contributors)
field of the `package.json` file. Beware to use the same format than for the author field
for the entries so that you'll get a mention in the `README.md` with a link to your website.
### License
To get your contribution merged, you must check the following.
- [ ] I read the project license in the LICENSE file
- [ ] I agree with publishing under this project license
<!--
If you already maintain several NPM modules / NodeJS
project, making significant changes on one of my modules
automatically legitimates you as a core developer.
This is because I could die or even not give a shit to
this project someday and I don't want people to get
stuck in such cases.
If you want to help, fill the following with to get
GitHub/NPM r/w access.
-->
### Join
- [ ] I wish to join the core team
- [ ] I agree that with great powers comes responsibilities
- [ ] I'm a nice person
My NPM username:
================================================
FILE: .github/workflows/test.yml
================================================
on: [push, pull_request]
name: Run tests
jobs:
test:
strategy:
matrix:
node: [20, 22, 23]
os: [macos-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'
- run: npm i -g npm@latest
- run: npm ci
- run: npm test
================================================
FILE: .gitignore
================================================
# This file is automatically generated by a `metapak`
# module. Do not change it elsewhere, changes would
# be overridden.
# Created by https://www.gitignore.io/api/osx,node,linux
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
### OSX ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# End of https://www.gitignore.io/api/osx,node,linux
# Coveralls key
.coveralls.yml
# Project custom ignored file
dist
build
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"gruntfuggly.todo-tree"
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"typescript.tsdk": "node_modules/typescript/lib"
}
================================================
FILE: CHANGELOG.md
================================================
## [8.0.1](https://github.com/nfroidure/ttf2woff2/compare/v8.0.0...v8.0.1) (2026-02-28)
### Bug Fixes
* **build:** include install script in metapak bundle files ([316db3a](https://github.com/nfroidure/ttf2woff2/commit/316db3a715b8a570bc84452e761a4b28c1e981a0))
* **install:** replace bash-specific syntax with cross-platform Node.js script ([91befd2](https://github.com/nfroidure/ttf2woff2/commit/91befd23a5c7d5b95e55fc5a53d74e070e418cc8))
# [8.0.0](https://github.com/nfroidure/ttf2woff2/compare/v7.0.0...v8.0.0) (2025-06-02)
### Bug Fixes
* **leak:** fix the error cas memory leak ([0896e18](https://github.com/nfroidure/ttf2woff2/commit/0896e183ee7f43d5f7cca5d4205557548dd86c71)), closes [#91](https://github.com/nfroidure/ttf2woff2/issues/91)
# [7.0.0](https://github.com/nfroidure/ttf2woff2/compare/v6.0.1...v7.0.0) (2025-05-22)
### Bug Fixes
* **ci:** add Node 22 and 23 to test matrix ([d335554](https://github.com/nfroidure/ttf2woff2/commit/d335554ad4679c4d508cb69141dba67de2bbcce5))
* **core:** fix TS errors ([7535aa1](https://github.com/nfroidure/ttf2woff2/commit/7535aa1288f9cb24be3e7026926b2b5973cbde20))
## [6.0.1](https://github.com/nfroidure/ttf2woff2/compare/v6.0.0...v6.0.1) (2024-07-20)
### Bug Fixes
* **ci:** fix CI runs ([4650b51](https://github.com/nfroidure/ttf2woff2/commit/4650b511a725a7f18128a0b3a691146cb40387d0))
* **core:** fix native bindings import ([420930f](https://github.com/nfroidure/ttf2woff2/commit/420930f8f2776904753d197a1f93263b1b68d66f))
# [6.0.0](https://github.com/nfroidure/ttf2woff2/compare/v5.0.0...v6.0.0) (2024-07-20)
### chore
* **dependencies:** update dependencies ([4319d41](https://github.com/nfroidure/ttf2woff2/commit/4319d41f552e563a1163f0a4a3664d68895871da))
### Features
* **core:** better choice between builds ([ff54055](https://github.com/nfroidure/ttf2woff2/commit/ff540555e6a55fcd4e7c69a8702167a1f9abfe1e)), closes [#22](https://github.com/nfroidure/ttf2woff2/issues/22) [#46](https://github.com/nfroidure/ttf2woff2/issues/46)
### BREAKING CHANGES
* **dependencies:** Requires Node20+, use ESM, provide TypeScript types
## [5.0.0](https://github.com/nfroidure/ttf2woff2/compare/v4.0.5...v5.0.0) (2022-12-06)
### Chore
- **bundle:** Update Emscripten builds
- **ci:** Add Node 19 to test matrix
- **dependencies:** Update dependencies (jest) and remove unsued dependencies
(mocha, mocha-lcov-reporter)
### BREAKING CHANGES
- **dependencies:** Drop Node 12 support
## [4.0.5](https://github.com/nfroidure/ttf2woff2/compare/v4.0.4...v4.0.5) (2022-04-23)
### Chore
- **bundle:** Update Emscripten builds
- **ci:** Add Node 18 to test matrix
- **dependencies:** Update dependencies (node-gyp, eslint, prettier) and remove
unsued dependencies (babel-eslint, @babel/register)
- **readme:** Add PowerShell use case
([#72](https://github.com/nfroidure/ttf2woff2/pull/72))
## [4.0.4](https://github.com/nfroidure/ttf2woff2/compare/v4.0.3...v4.0.4) (2021-05-29)
### Chore
- **dependencies:** Update jest, mocha, node-gyp
([#71](https://github.com/nfroidure/ttf2woff2/pull/71))
## [4.0.3](https://github.com/nfroidure/ttf2woff2/compare/v4.0.2...v4.0.3) (2021-05-29)
### Bug Fixes
- **build:** support Node 16
([b8a8986](https://github.com/nfroidure/ttf2woff2/commit/b8a898636b5d66e55bc1344caa15a03f49c46b59))
## [4.0.2](https://github.com/nfroidure/ttf2woff2/compare/v4.0.1...v4.0.2) (2021-03-15)
### Bug Fixes
- **docs:** fix the readme
([acb62c5](https://github.com/nfroidure/ttf2woff2/commit/acb62c579974b510a4d824ee5a6fed74923f3935))
## [4.0.1](https://github.com/nfroidure/ttf2woff2/compare/v4.0.0...v4.0.1) (2020-12-22)
### Bug Fixes
- **bundle:** add necessary files to the bundle
([fc9bb76](https://github.com/nfroidure/ttf2woff2/commit/fc9bb76fa8a51b55a81aec5a7a8efb72722860cc))
## [4.0.0](https://github.com/nfroidure/ttf2woff2/compare/v3.0.0...v4.0.0) (2020-12-22)
### Chore
- **dependencies:** update dependencies
([0657e8d](https://github.com/nfroidure/ttf2woff2/commit/0657e8df60fa5b984406cf0d33b86c64c759a2c8))
### BREAKING CHANGES
- **dependencies:** Requiring Node12 to work
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright © 2017 Nicolas Froidure
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.
================================================
FILE: README.md
================================================
[//]: # ( )
[//]: # (This file is automatically generated by a `metapak`)
[//]: # (module. Do not change it except between the)
[//]: # (`content:start/end` flags, your changes would)
[//]: # (be overridden.)
[//]: # ( )
# ttf2woff2
> Convert TTF files to WOFF2 ones.
[](https://github.com/nfroidure/ttf2woff2/blob/main/LICENSE)
[//]: # (::contents:start)
This is a NodeJS wrapper for the Google [WOFF2](https://github.com/google/woff2)
project. If the C++ wrapper compilation fail, it
[fallbacks to an Emscripten build](http://insertafter.com/en/blog/native-node-module.html).
## Usage
### CLI
Install `ttf2woff2` globally, then:
```sh
cat font.ttf | ttf2woff2 > font.woff2
```
On Windows without `cat`, use (in PowerShell):
```pwsh
Start-Process -NoNewWindow -Wait ttf2woff2.cmd -RedirectStandardInput font.ttf -RedirectStandardOutput font.woff2
# OR
start-process -nnw -wait ttf2woff2.cmd -rsi font.ttf -rso font.woff2
```
### API
```js
import { readFile, writeFile } from 'node:fs/promises';
import ttf2woff2 from 'ttf2woff2';
const input = await readFile('font.ttf');
await writeFile('font.woff2', ttf2woff2(input));
```
## Development
To build the binary, clone the repository and run the following:
```
## Setup (works for Ubuntu/Linux, may be different on other OS)
apt-get install make g++
## Actual build
npm i
npm run configure
npm run make
```
To build the Emscripten fallback, install [Emscripten](https://emscripten.org/) and run:
```
npm run emcc
```
Finally the build can be tested:
```sh
npm run build
npm t
```
## Contributing
Feel free to push your code if you agree with publishing under the MIT license.
[//]: # (::contents:end)
# Authors
- [Nicolas Froidure](https://insertafter.com/en/index.html)
- [Anders Kaseorg](mailto:andersk@mit.edu)
# License
[MIT](https://github.com/nfroidure/ttf2woff2/blob/main/LICENSE)
================================================
FILE: bin/ttf2woff2.js
================================================
#! /usr/bin/env node
import {
BufferStream
} from 'bufferstreams';
import ttf2woff2 from '../dist/index.js';
process.stdin
.pipe(
new BufferStream(function (err, buf, cb) {
if (err) {
throw err;
}
cb(null, ttf2woff2(buf));
}),
)
.pipe(process.stdout);
================================================
FILE: binding.gyp
================================================
{
"targets": [
{
"target_name": "addon",
"sources": [
"csrc/addon.cc",
"csrc/woff2/glyph.cc",
"csrc/woff2/font.cc",
"csrc/woff2/normalize.cc",
"csrc/woff2/table_tags.cc",
"csrc/woff2/transform.cc",
"csrc/woff2/variable_length.cc",
"csrc/woff2/woff2_common.cc",
"csrc/woff2/woff2_enc.cc",
"csrc/enc/backward_references.cc",
"csrc/enc/block_splitter.cc",
"csrc/enc/brotli_bit_stream.cc",
"csrc/enc/encode.cc",
"csrc/enc/encode_parallel.cc",
"csrc/enc/entropy_encode.cc",
"csrc/enc/histogram.cc",
"csrc/enc/literal_cost.cc",
"csrc/enc/metablock.cc",
"csrc/enc/streams.cc"
],
"include_dirs" : [
"<!(node -e \"require('nan')\")"
],
"cflags": [
"-w"
],
"conditions": [
[ "OS==\"mac\"", {
"xcode_settings": {
"OTHER_CPLUSPLUSFLAGS": [ "-stdlib=libc++", "-w" ],
"OTHER_LDFLAGS": [ "-stdlib=libc++" ],
"MACOSX_DEPLOYMENT_TARGET": "10.7"
}
}]
]
}
]
}
================================================
FILE: csrc/addon.cc
================================================
#include <nan.h>
#include <node.h>
#include <node_buffer.h>
#include <stdlib.h>
#include "./woff2/woff2_enc.h"
using namespace v8;
NAN_METHOD(convert) {
Isolate *isolate = info.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
Local<Object> inputBuffer = info[0]->ToObject(context).ToLocalChecked();
if (!node::Buffer::HasInstance(inputBuffer)) {
Nan::ThrowError(Nan::TypeError("First arg should be a Buffer"));
return;
}
size_t input_length = node::Buffer::Length(inputBuffer);
char* input_data = node::Buffer::Data(inputBuffer);
// Determine the maximum needed length
size_t max_output_length = woff2::MaxWOFF2CompressedSize(
reinterpret_cast<const uint8_t*>(input_data), input_length);
size_t actual_output_length = max_output_length;
char* output_data = (char*) calloc(max_output_length, 1);
// Create the Woff2 font
if (!woff2::ConvertTTFToWOFF2(
reinterpret_cast<const uint8_t*>(input_data), input_length,
reinterpret_cast<uint8_t*>(output_data), &actual_output_length
)) {
free(output_data);
Nan::ThrowError(Nan::Error("E_CONVERT_ERROR"));
return;
}
// Free the unused memory
output_data = (char*) realloc(output_data, actual_output_length);
Nan::MaybeLocal<v8::Object> outputBuffer = Nan::NewBuffer(
output_data,
actual_output_length
);
info.GetReturnValue().Set(outputBuffer.ToLocalChecked());
}
NAN_MODULE_INIT(Init) {
Nan::Set(target, Nan::New("convert").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(convert)).ToLocalChecked());
}
NODE_MODULE(addon, Init)
================================================
FILE: csrc/enc/backward_references.cc
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Function to find backward reference copies.
#include "./backward_references.h"
#include <algorithm>
#include <vector>
#include "./command.h"
namespace brotli {
template<typename Hasher, bool kUseCostModel, bool kUseDictionary>
void CreateBackwardReferences(size_t num_bytes,
size_t position,
const uint8_t* ringbuffer,
size_t ringbuffer_mask,
const float* literal_cost,
size_t literal_cost_mask,
const size_t max_backward_limit,
const double base_min_score,
const int quality,
Hasher* hasher,
int* dist_cache,
int* last_insert_len,
Command* commands,
int* num_commands) {
if (num_bytes >= 3 && 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.
hasher->Store(&ringbuffer[(position - 3) & ringbuffer_mask],
position - 3);
hasher->Store(&ringbuffer[(position - 2) & ringbuffer_mask],
position - 2);
hasher->Store(&ringbuffer[(position - 1) & ringbuffer_mask],
position - 1);
}
const Command * const orig_commands = commands;
int insert_length = *last_insert_len;
size_t i = position & ringbuffer_mask;
const int i_diff = position - i;
const size_t i_end = i + num_bytes;
// For speed up heuristics for random data.
const int random_heuristics_window_size = quality < 9 ? 64 : 512;
int apply_random_heuristics = i + random_heuristics_window_size;
double average_cost = 5.4;
if (kUseCostModel) {
average_cost = 0.0;
for (int k = position; k < position + num_bytes; ++k) {
average_cost += literal_cost[k & literal_cost_mask];
}
if (num_bytes > 0) {
average_cost /= num_bytes;
}
}
// M1 match is for considering for two repeated copies, if moving
// one literal form the previous copy to the current one allows the
// current copy to be more efficient (because the way static dictionary
// codes words). M1 matching improves text compression density by ~0.15 %.
bool match_found_M1 = false;
int best_len_M1 = 0;
int best_len_code_M1 = 0;
int best_dist_M1 = 0;
double best_score_M1 = 0;
while (i + 3 < i_end) {
int max_length = i_end - i;
size_t max_distance = std::min(i + i_diff, max_backward_limit);
double min_score = base_min_score;
if (kUseCostModel && insert_length < 8) {
double cost_diff[8] =
{ 0.1, 0.038, 0.019, 0.013, 0.001, 0.001, 0.001, 0.001 };
min_score += cost_diff[insert_length];
}
int best_len = 0;
int best_len_code = 0;
int best_dist = 0;
double best_score = min_score;
bool match_found = hasher->FindLongestMatch(
ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, average_cost,
dist_cache, i + i_diff, max_length, max_distance,
&best_len, &best_len_code, &best_dist, &best_score);
if (match_found) {
if (kUseDictionary && match_found_M1 && best_score_M1 > best_score) {
// Two copies after each other. Take the last literal from the
// last copy, and use it as the first of this one.
Command prev_cmd = commands[-1];
commands[-1] = Command(prev_cmd.insert_len_,
prev_cmd.copy_len_ - 1,
prev_cmd.copy_len_ - 1,
prev_cmd.DistanceCode());
hasher->Store(ringbuffer + i, i + i_diff);
--i;
best_len = best_len_M1;
best_len_code = best_len_code_M1;
best_dist = best_dist_M1;
best_score = best_score_M1;
} else {
// Found a match. Let's look for something even better ahead.
int delayed_backward_references_in_row = 0;
for (;;) {
--max_length;
int best_len_2 = quality < 4 ? std::min(best_len - 1, max_length) : 0;
int best_len_code_2 = 0;
int best_dist_2 = 0;
double best_score_2 = min_score;
max_distance = std::min(i + i_diff + 1, max_backward_limit);
hasher->Store(ringbuffer + i, i + i_diff);
match_found = hasher->FindLongestMatch(
ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, average_cost,
dist_cache, i + i_diff + 1, max_length, max_distance,
&best_len_2, &best_len_code_2, &best_dist_2, &best_score_2);
double cost_diff_lazy = 7.0;
if (kUseCostModel) {
cost_diff_lazy = 0.0;
if (best_len >= 4) {
cost_diff_lazy +=
literal_cost[(i + 4) & literal_cost_mask] - average_cost;
}
{
const int tail_length = best_len_2 - best_len + 1;
for (int k = 0; k < tail_length; ++k) {
cost_diff_lazy -=
literal_cost[(i + best_len + k) & literal_cost_mask] -
average_cost;
}
}
// If we are not inserting any symbols, inserting one is more
// expensive than if we were inserting symbols anyways.
if (insert_length < 1) {
cost_diff_lazy += 0.97;
}
// Add bias to slightly avoid lazy matching.
cost_diff_lazy += 2.0 + delayed_backward_references_in_row * 0.2;
cost_diff_lazy += 0.04 * literal_cost[i & literal_cost_mask];
}
if (match_found && best_score_2 >= best_score + cost_diff_lazy) {
// Ok, let's just write one byte for now and start a match from the
// next byte.
++i;
++insert_length;
best_len = best_len_2;
best_len_code = best_len_code_2;
best_dist = best_dist_2;
best_score = best_score_2;
if (++delayed_backward_references_in_row < 4) {
continue;
}
}
break;
}
}
apply_random_heuristics =
i + 2 * best_len + random_heuristics_window_size;
max_distance = std::min(i + i_diff, max_backward_limit);
int distance_code = best_dist + 16;
if (best_dist <= max_distance) {
if (best_dist == dist_cache[0]) {
distance_code = 1;
} else if (best_dist == dist_cache[1]) {
distance_code = 2;
} else if (best_dist == dist_cache[2]) {
distance_code = 3;
} else if (best_dist == dist_cache[3]) {
distance_code = 4;
} else if (quality > 1 && best_dist >= 6) {
for (int k = 4; k < kNumDistanceShortCodes; ++k) {
int idx = kDistanceCacheIndex[k];
int candidate = dist_cache[idx] + kDistanceCacheOffset[k];
static const int kLimits[16] = { 0, 0, 0, 0,
6, 6, 11, 11,
11, 11, 11, 11,
12, 12, 12, 12 };
if (best_dist == candidate && best_dist >= kLimits[k]) {
distance_code = k + 1;
break;
}
}
}
if (distance_code > 1) {
dist_cache[3] = dist_cache[2];
dist_cache[2] = dist_cache[1];
dist_cache[1] = dist_cache[0];
dist_cache[0] = best_dist;
}
}
Command cmd(insert_length, best_len, best_len_code, distance_code);
*commands++ = cmd;
insert_length = 0;
if (kUseDictionary) {
++i;
// Copy all copied literals to the hasher, except the last one.
// We cannot store the last one yet, otherwise we couldn't find
// the possible M1 match.
for (int j = 1; j < best_len - 1; ++j) {
if (i + 3 < i_end) {
hasher->Store(ringbuffer + i, i + i_diff);
}
++i;
}
// Prepare M1 match.
if (hasher->HasStaticDictionary() &&
best_len >= 4 && i + 20 < i_end && best_dist <= max_distance) {
max_distance = std::min(i + i_diff, max_backward_limit);
best_score_M1 = min_score;
match_found_M1 = hasher->FindLongestMatch(
ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, average_cost,
dist_cache, i + i_diff, i_end - i, max_distance,
&best_len_M1, &best_len_code_M1, &best_dist_M1, &best_score_M1);
} else {
match_found_M1 = false;
}
if (kUseCostModel) {
// This byte is just moved from the previous copy to the current,
// that is no gain.
best_score_M1 -= literal_cost[i & literal_cost_mask];
// Adjust for losing the opportunity for lazy matching.
best_score_M1 -= 3.75;
}
// Store the last one of the match.
if (i + 3 < i_end) {
hasher->Store(ringbuffer + i, i + i_diff);
}
++i;
} else {
// Put the hash keys into the table, if there are enough
// bytes left.
for (int j = 1; j < best_len; ++j) {
hasher->Store(&ringbuffer[i + j], i + i_diff + j);
}
i += best_len;
}
} else {
match_found_M1 = false;
++insert_length;
hasher->Store(ringbuffer + i, i + i_diff);
++i;
// 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 (i > apply_random_heuristics) {
// Going through uncompressible data, jump.
if (i > 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.
int i_jump = std::min(i + 16, i_end - 4);
for (; i < i_jump; i += 4) {
hasher->Store(ringbuffer + i, i + i_diff);
insert_length += 4;
}
} else {
int i_jump = std::min(i + 8, i_end - 3);
for (; i < i_jump; i += 2) {
hasher->Store(ringbuffer + i, i + i_diff);
insert_length += 2;
}
}
}
}
}
insert_length += (i_end - i);
*last_insert_len = insert_length;
*num_commands += (commands - orig_commands);
}
void CreateBackwardReferences(size_t num_bytes,
size_t position,
const uint8_t* ringbuffer,
size_t ringbuffer_mask,
const float* literal_cost,
size_t literal_cost_mask,
const size_t max_backward_limit,
const double base_min_score,
const int quality,
Hashers* hashers,
int hash_type,
int* dist_cache,
int* last_insert_len,
Command* commands,
int* num_commands) {
switch (hash_type) {
case 1:
CreateBackwardReferences<Hashers::H1, false, false>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h1.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
case 2:
CreateBackwardReferences<Hashers::H2, false, false>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h2.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
case 3:
CreateBackwardReferences<Hashers::H3, false, false>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h3.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
case 4:
CreateBackwardReferences<Hashers::H4, false, false>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h4.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
case 5:
CreateBackwardReferences<Hashers::H5, false, false>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h5.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
case 6:
CreateBackwardReferences<Hashers::H6, false, false>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h6.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
case 7:
CreateBackwardReferences<Hashers::H7, false, false>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h7.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
case 8:
CreateBackwardReferences<Hashers::H8, true, true>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h8.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
case 9:
CreateBackwardReferences<Hashers::H9, true, false>(
num_bytes, position, ringbuffer, ringbuffer_mask,
literal_cost, literal_cost_mask, max_backward_limit, base_min_score,
quality, hashers->hash_h9.get(), dist_cache, last_insert_len,
commands, num_commands);
break;
default:
break;
}
}
} // namespace brotli
================================================
FILE: csrc/enc/backward_references.h
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Function to find backward reference copies.
#ifndef BROTLI_ENC_BACKWARD_REFERENCES_H_
#define BROTLI_ENC_BACKWARD_REFERENCES_H_
#include <stdint.h>
#include <vector>
#include "./hash.h"
#include "./command.h"
namespace brotli {
void CreateBackwardReferences(size_t num_bytes,
size_t position,
const uint8_t* ringbuffer,
size_t ringbuffer_mask,
const float* literal_cost,
size_t literal_cost_mask,
const size_t max_backward_limit,
const double base_min_score,
const int quality,
Hashers* hashers,
int hash_type,
int* dist_cache,
int* last_insert_len,
Command* commands,
int* num_commands);
} // namespace brotli
#endif // BROTLI_ENC_BACKWARD_REFERENCES_H_
================================================
FILE: csrc/enc/bit_cost.h
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Functions to estimate the bit cost of Huffman trees.
#ifndef BROTLI_ENC_BIT_COST_H_
#define BROTLI_ENC_BIT_COST_H_
#include <stdint.h>
#include "./entropy_encode.h"
#include "./fast_log.h"
namespace brotli {
static inline double BitsEntropy(const int *population, int size) {
int sum = 0;
double retval = 0;
const int *population_end = population + size;
int p;
if (size & 1) {
goto odd_number_of_elements_left;
}
while (population < population_end) {
p = *population++;
sum += p;
retval -= p * FastLog2(p);
odd_number_of_elements_left:
p = *population++;
sum += p;
retval -= p * FastLog2(p);
}
if (sum) retval += sum * FastLog2(sum);
if (retval < sum) {
// At least one bit per literal is needed.
retval = sum;
}
return retval;
}
static const int kHuffmanExtraBits[kCodeLengthCodes] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3,
};
static inline int HuffmanTreeBitCost(const int* counts, const uint8_t* depth) {
int nbits = 0;
for (int i = 0; i < kCodeLengthCodes; ++i) {
nbits += counts[i] * (depth[i] + kHuffmanExtraBits[i]);
}
return nbits;
}
static inline int HuffmanTreeBitCost(
const Histogram<kCodeLengthCodes>& histogram,
const EntropyCode<kCodeLengthCodes>& entropy) {
return HuffmanTreeBitCost(&histogram.data_[0], &entropy.depth_[0]);
}
static inline int HuffmanBitCost(const uint8_t* depth, int length) {
int max_depth = 1;
int histogram[kCodeLengthCodes] = { 0 };
int tail_start = 0;
int prev_value = 8;
// compute histogram of compacted huffman tree
for (int i = 0; i < length;) {
const int value = depth[i];
if (value > max_depth) {
max_depth = value;
}
int reps = 1;
for (int k = i + 1; k < length && depth[k] == value; ++k) {
++reps;
}
i += reps;
if (i == length && value == 0)
break;
if (value == 0) {
if (reps < 3) {
histogram[0] += reps;
} else {
reps -= 2;
while (reps > 0) {
++histogram[17];
reps >>= 3;
}
}
} else {
tail_start = i;
if (value != prev_value) {
++histogram[value];
--reps;
}
prev_value = value;
if (reps < 3) {
histogram[value] += reps;
} else {
reps -= 2;
while (reps > 0) {
++histogram[16];
reps >>= 2;
}
}
}
}
// create huffman tree of huffman tree
uint8_t cost[kCodeLengthCodes] = { 0 };
CreateHuffmanTree(histogram, kCodeLengthCodes, 7, cost);
// account for rle extra bits
cost[16] += 2;
cost[17] += 3;
int tree_size = 0;
int bits = 18 + 2 * max_depth; // huffman tree of huffman tree cost
for (int i = 0; i < kCodeLengthCodes; ++i) {
bits += histogram[i] * cost[i]; // huffman tree bit cost
tree_size += histogram[i];
}
return bits;
}
template<int kSize>
double PopulationCost(const Histogram<kSize>& histogram) {
if (histogram.total_count_ == 0) {
return 12;
}
int count = 0;
for (int i = 0; i < kSize && count < 5; ++i) {
if (histogram.data_[i] > 0) {
++count;
}
}
if (count == 1) {
return 12;
}
if (count == 2) {
return 20 + histogram.total_count_;
}
uint8_t depth[kSize] = { 0 };
CreateHuffmanTree(&histogram.data_[0], kSize, 15, depth);
int bits = 0;
for (int i = 0; i < kSize; ++i) {
bits += histogram.data_[i] * depth[i];
}
if (count == 3) {
bits += 28;
} else if (count == 4) {
bits += 37;
} else {
bits += HuffmanBitCost(depth, kSize);
}
return bits;
}
} // namespace brotli
#endif // BROTLI_ENC_BIT_COST_H_
================================================
FILE: csrc/enc/block_splitter.cc
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Block split point selection utilities.
#include "./block_splitter.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <map>
#include "./cluster.h"
#include "./command.h"
#include "./fast_log.h"
#include "./histogram.h"
namespace brotli {
static const int kMaxLiteralHistograms = 100;
static const int kMaxCommandHistograms = 50;
static const double kLiteralBlockSwitchCost = 28.1;
static const double kCommandBlockSwitchCost = 13.5;
static const double kDistanceBlockSwitchCost = 14.6;
static const int kLiteralStrideLength = 70;
static const int kCommandStrideLength = 40;
static const int kSymbolsPerLiteralHistogram = 544;
static const int kSymbolsPerCommandHistogram = 530;
static const int kSymbolsPerDistanceHistogram = 544;
static const int kMinLengthForBlockSplitting = 128;
static const int kIterMulForRefining = 2;
static const int kMinItersForRefining = 100;
void CopyLiteralsToByteArray(const Command* cmds,
const size_t num_commands,
const uint8_t* data,
std::vector<uint8_t>* literals) {
// Count how many we have.
size_t total_length = 0;
for (int i = 0; i < num_commands; ++i) {
total_length += cmds[i].insert_len_;
}
if (total_length == 0) {
return;
}
// Allocate.
literals->resize(total_length);
// Loop again, and copy this time.
size_t pos = 0;
size_t from_pos = 0;
for (int i = 0; i < num_commands && pos < total_length; ++i) {
memcpy(&(*literals)[pos], data + from_pos, cmds[i].insert_len_);
pos += cmds[i].insert_len_;
from_pos += cmds[i].insert_len_ + cmds[i].copy_len_;
}
}
void CopyCommandsToByteArray(const Command* cmds,
const size_t num_commands,
std::vector<uint16_t>* insert_and_copy_codes,
std::vector<uint8_t>* distance_prefixes) {
for (int i = 0; i < num_commands; ++i) {
const Command& cmd = cmds[i];
insert_and_copy_codes->push_back(cmd.cmd_prefix_);
if (cmd.copy_len_ > 0 && cmd.cmd_prefix_ >= 128) {
distance_prefixes->push_back(cmd.dist_prefix_);
}
}
}
inline static unsigned int MyRand(unsigned int* seed) {
*seed *= 16807U;
if (*seed == 0) {
*seed = 1;
}
return *seed;
}
template<typename HistogramType, typename DataType>
void InitialEntropyCodes(const DataType* data, size_t length,
int literals_per_histogram,
int max_histograms,
size_t stride,
std::vector<HistogramType>* vec) {
int total_histograms = length / literals_per_histogram + 1;
if (total_histograms > max_histograms) {
total_histograms = max_histograms;
}
unsigned int seed = 7;
int block_length = length / total_histograms;
for (int i = 0; i < total_histograms; ++i) {
int pos = length * i / total_histograms;
if (i != 0) {
pos += MyRand(&seed) % block_length;
}
if (pos + stride >= length) {
pos = length - stride - 1;
}
HistogramType histo;
histo.Add(data + pos, stride);
vec->push_back(histo);
}
}
template<typename HistogramType, typename DataType>
void RandomSample(unsigned int* seed,
const DataType* data,
size_t length,
size_t stride,
HistogramType* sample) {
size_t pos = 0;
if (stride >= length) {
pos = 0;
stride = length;
} else {
pos = MyRand(seed) % (length - stride + 1);
}
sample->Add(data + pos, stride);
}
template<typename HistogramType, typename DataType>
void RefineEntropyCodes(const DataType* data, size_t length,
size_t stride,
std::vector<HistogramType>* vec) {
int iters =
kIterMulForRefining * length / stride + kMinItersForRefining;
unsigned int seed = 7;
iters = ((iters + vec->size() - 1) / vec->size()) * vec->size();
for (int iter = 0; iter < iters; ++iter) {
HistogramType sample;
RandomSample(&seed, data, length, stride, &sample);
int ix = iter % vec->size();
(*vec)[ix].AddHistogram(sample);
}
}
inline static float BitCost(int total, int count) {
return count == 0 ? FastLog2(total) + 2 : FastLog2(total) - FastLog2(count);
}
template<typename DataType, int kSize>
void FindBlocks(const DataType* data, const size_t length,
const double block_switch_bitcost,
const std::vector<Histogram<kSize> > &vec,
uint8_t *block_id) {
if (vec.size() <= 1) {
for (int i = 0; i < length; ++i) {
block_id[i] = 0;
}
return;
}
int vecsize = vec.size();
double* insert_cost = new double[kSize * vecsize];
memset(insert_cost, 0, sizeof(insert_cost[0]) * kSize * vecsize);
for (int i = 0; i < kSize; ++i) {
for (int j = 0; j < vecsize; ++j) {
insert_cost[i * vecsize + j] =
BitCost(vec[j].total_count_, vec[j].data_[i]);
}
}
double *cost = new double[vecsize];
memset(cost, 0, sizeof(cost[0]) * vecsize);
bool* switch_signal = new bool[length * vecsize];
memset(switch_signal, 0, sizeof(switch_signal[0]) * length * vecsize);
// 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.
for (size_t byte_ix = 0; byte_ix < length; ++byte_ix) {
int ix = byte_ix * vecsize;
int insert_cost_ix = data[byte_ix] * vecsize;
double min_cost = 1e99;
for (int k = 0; k < vecsize; ++k) {
// We are coding the symbol in data[byte_ix] 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] = k;
}
}
double block_switch_cost = block_switch_bitcost;
// More blocks for the beginning.
if (byte_ix < 2000) {
block_switch_cost *= 0.77 + 0.07 * byte_ix / 2000;
}
for (int k = 0; k < vecsize; ++k) {
cost[k] -= min_cost;
if (cost[k] >= block_switch_cost) {
cost[k] = block_switch_cost;
switch_signal[ix + k] = true;
}
}
}
// Now trace back from the last position and switch at the marked places.
int byte_ix = length - 1;
int ix = byte_ix * vecsize;
int cur_id = block_id[byte_ix];
while (byte_ix > 0) {
--byte_ix;
ix -= vecsize;
if (switch_signal[ix + cur_id]) {
cur_id = block_id[byte_ix];
}
block_id[byte_ix] = cur_id;
}
delete[] insert_cost;
delete[] cost;
delete[] switch_signal;
}
int RemapBlockIds(uint8_t* block_ids, const size_t length) {
std::map<uint8_t, uint8_t> new_id;
int next_id = 0;
for (int i = 0; i < length; ++i) {
if (new_id.find(block_ids[i]) == new_id.end()) {
new_id[block_ids[i]] = next_id;
++next_id;
}
}
for (int i = 0; i < length; ++i) {
block_ids[i] = new_id[block_ids[i]];
}
return next_id;
}
template<typename HistogramType, typename DataType>
void BuildBlockHistograms(const DataType* data, const size_t length,
uint8_t* block_ids,
std::vector<HistogramType>* histograms) {
int num_types = RemapBlockIds(block_ids, length);
histograms->clear();
histograms->resize(num_types);
for (int i = 0; i < length; ++i) {
(*histograms)[block_ids[i]].Add(data[i]);
}
}
template<typename HistogramType, typename DataType>
void ClusterBlocks(const DataType* data, const size_t length,
uint8_t* block_ids) {
std::vector<HistogramType> histograms;
std::vector<int> block_index(length);
int cur_idx = 0;
HistogramType cur_histogram;
for (int i = 0; i < length; ++i) {
bool block_boundary = (i + 1 == length || block_ids[i] != block_ids[i + 1]);
block_index[i] = cur_idx;
cur_histogram.Add(data[i]);
if (block_boundary) {
histograms.push_back(cur_histogram);
cur_histogram.Clear();
++cur_idx;
}
}
std::vector<HistogramType> clustered_histograms;
std::vector<int> histogram_symbols;
// Block ids need to fit in one byte.
static const int kMaxNumberOfBlockTypes = 256;
ClusterHistograms(histograms, 1, histograms.size(),
kMaxNumberOfBlockTypes,
&clustered_histograms,
&histogram_symbols);
for (int i = 0; i < length; ++i) {
block_ids[i] = histogram_symbols[block_index[i]];
}
}
void BuildBlockSplit(const std::vector<uint8_t>& block_ids, BlockSplit* split) {
int cur_id = block_ids[0];
int cur_length = 1;
split->num_types = -1;
for (int i = 1; i < block_ids.size(); ++i) {
if (block_ids[i] != cur_id) {
split->types.push_back(cur_id);
split->lengths.push_back(cur_length);
split->num_types = std::max(split->num_types, cur_id);
cur_id = block_ids[i];
cur_length = 0;
}
++cur_length;
}
split->types.push_back(cur_id);
split->lengths.push_back(cur_length);
split->num_types = std::max(split->num_types, cur_id);
++split->num_types;
}
template<typename HistogramType, typename DataType>
void SplitByteVector(const std::vector<DataType>& data,
const int literals_per_histogram,
const int max_histograms,
const int sampling_stride_length,
const double block_switch_cost,
BlockSplit* split) {
if (data.empty()) {
split->num_types = 1;
return;
} else if (data.size() < kMinLengthForBlockSplitting) {
split->num_types = 1;
split->types.push_back(0);
split->lengths.push_back(data.size());
return;
}
std::vector<HistogramType> histograms;
// Find good entropy codes.
InitialEntropyCodes(data.data(), data.size(),
literals_per_histogram,
max_histograms,
sampling_stride_length,
&histograms);
RefineEntropyCodes(data.data(), data.size(),
sampling_stride_length,
&histograms);
// Find a good path through literals with the good entropy codes.
std::vector<uint8_t> block_ids(data.size());
for (int i = 0; i < 10; ++i) {
FindBlocks(data.data(), data.size(),
block_switch_cost,
histograms,
&block_ids[0]);
BuildBlockHistograms(data.data(), data.size(), &block_ids[0], &histograms);
}
ClusterBlocks<HistogramType>(data.data(), data.size(), &block_ids[0]);
BuildBlockSplit(block_ids, split);
}
void SplitBlock(const Command* cmds,
const size_t num_commands,
const uint8_t* data,
BlockSplit* literal_split,
BlockSplit* insert_and_copy_split,
BlockSplit* dist_split) {
// Create a continuous array of literals.
std::vector<uint8_t> literals;
CopyLiteralsToByteArray(cmds, num_commands, data, &literals);
// Compute prefix codes for commands.
std::vector<uint16_t> insert_and_copy_codes;
std::vector<uint8_t> distance_prefixes;
CopyCommandsToByteArray(cmds, num_commands,
&insert_and_copy_codes,
&distance_prefixes);
SplitByteVector<HistogramLiteral>(
literals,
kSymbolsPerLiteralHistogram, kMaxLiteralHistograms,
kLiteralStrideLength, kLiteralBlockSwitchCost,
literal_split);
SplitByteVector<HistogramCommand>(
insert_and_copy_codes,
kSymbolsPerCommandHistogram, kMaxCommandHistograms,
kCommandStrideLength, kCommandBlockSwitchCost,
insert_and_copy_split);
SplitByteVector<HistogramDistance>(
distance_prefixes,
kSymbolsPerDistanceHistogram, kMaxCommandHistograms,
kCommandStrideLength, kDistanceBlockSwitchCost,
dist_split);
}
void SplitBlockByTotalLength(const Command* all_commands,
const size_t num_commands,
int input_size,
int target_length,
std::vector<std::vector<Command> >* blocks) {
int num_blocks = input_size / target_length + 1;
int length_limit = input_size / num_blocks + 1;
int total_length = 0;
std::vector<Command> cur_block;
for (int i = 0; i < num_commands; ++i) {
const Command& cmd = all_commands[i];
int cmd_length = cmd.insert_len_ + cmd.copy_len_;
if (total_length > length_limit) {
blocks->push_back(cur_block);
cur_block.clear();
total_length = 0;
}
cur_block.push_back(cmd);
total_length += cmd_length;
}
blocks->push_back(cur_block);
}
} // namespace brotli
================================================
FILE: csrc/enc/block_splitter.h
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Block split point selection utilities.
#ifndef BROTLI_ENC_BLOCK_SPLITTER_H_
#define BROTLI_ENC_BLOCK_SPLITTER_H_
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <vector>
#include <utility>
#include "./command.h"
#include "./metablock.h"
namespace brotli {
struct BlockSplitIterator {
explicit BlockSplitIterator(const BlockSplit& split)
: split_(split), idx_(0), type_(0), length_(0) {
if (!split.lengths.empty()) {
length_ = split.lengths[0];
}
}
void Next() {
if (length_ == 0) {
++idx_;
type_ = split_.types[idx_];
length_ = split_.lengths[idx_];
}
--length_;
}
const BlockSplit& split_;
int idx_;
int type_;
int length_;
};
void CopyLiteralsToByteArray(const Command* cmds,
const size_t num_commands,
const uint8_t* data,
std::vector<uint8_t>* literals);
void SplitBlock(const Command* cmds,
const size_t num_commands,
const uint8_t* data,
BlockSplit* literal_split,
BlockSplit* insert_and_copy_split,
BlockSplit* dist_split);
void SplitBlockByTotalLength(const Command* all_commands,
const size_t num_commands,
int input_size,
int target_length,
std::vector<std::vector<Command> >* blocks);
} // namespace brotli
#endif // BROTLI_ENC_BLOCK_SPLITTER_H_
================================================
FILE: csrc/enc/brotli_bit_stream.cc
================================================
// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// 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 <algorithm>
#include <limits>
#include <vector>
#include "./bit_cost.h"
#include "./context.h"
#include "./entropy_encode.h"
#include "./fast_log.h"
#include "./prefix.h"
#include "./write_bits.h"
namespace brotli {
// returns false if fail
// nibblesbits represents the 2 bits to encode MNIBBLES (0-3)
bool EncodeMlen(size_t length, int* bits, int* numbits, int* nibblesbits) {
length--; // MLEN - 1 is encoded
int lg = length == 0 ? 1 : Log2Floor(length) + 1;
if (lg > 24) return false;
int mnibbles = (lg < 16 ? 16 : (lg + 3)) / 4;
*nibblesbits = mnibbles - 4;
*numbits = mnibbles * 4;
*bits = length;
return true;
}
void StoreVarLenUint8(int n, int* storage_ix, uint8_t* storage) {
if (n == 0) {
WriteBits(1, 0, storage_ix, storage);
} else {
WriteBits(1, 1, storage_ix, storage);
int nbits = Log2Floor(n);
WriteBits(3, nbits, storage_ix, storage);
WriteBits(nbits, n - (1 << nbits), storage_ix, storage);
}
}
bool StoreCompressedMetaBlockHeader(bool final_block,
size_t length,
int* storage_ix,
uint8_t* storage) {
// Write ISLAST bit.
WriteBits(1, final_block, storage_ix, storage);
// Write ISEMPTY bit.
if (final_block) {
WriteBits(1, length == 0, storage_ix, storage);
if (length == 0) {
return true;
}
}
if (length == 0) {
// Only the last meta-block can be empty.
return false;
}
int lenbits;
int nlenbits;
int nibblesbits;
if (!EncodeMlen(length, &lenbits, &nlenbits, &nibblesbits)) {
return false;
}
WriteBits(2, nibblesbits, storage_ix, storage);
WriteBits(nlenbits, lenbits, storage_ix, storage);
if (!final_block) {
// Write ISUNCOMPRESSED bit.
WriteBits(1, 0, storage_ix, storage);
}
return true;
}
bool StoreUncompressedMetaBlockHeader(size_t length,
int* storage_ix,
uint8_t* storage) {
// Write ISLAST bit. Uncompressed block cannot be the last one, so set to 0.
WriteBits(1, 0, storage_ix, storage);
int lenbits;
int nlenbits;
int nibblesbits;
if (!EncodeMlen(length, &lenbits, &nlenbits, &nibblesbits)) {
return false;
}
WriteBits(2, nibblesbits, storage_ix, storage);
WriteBits(nlenbits, lenbits, storage_ix, storage);
// Write ISUNCOMPRESSED bit.
WriteBits(1, 1, storage_ix, storage);
return true;
}
void StoreHuffmanTreeOfHuffmanTreeToBitMask(
const int num_codes,
const uint8_t *code_length_bitdepth,
int *storage_ix,
uint8_t *storage) {
static const uint8_t kStorageOrder[kCodeLengthCodes] = {
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 uint8_t kHuffmanBitLengthHuffmanCodeSymbols[6] = {
0, 7, 3, 2, 1, 15
};
static const uint8_t kHuffmanBitLengthHuffmanCodeBitLengths[6] = {
2, 4, 3, 2, 2, 4
};
// Throw away trailing zeros:
int codes_to_store = kCodeLengthCodes;
if (num_codes > 1) {
for (; codes_to_store > 0; --codes_to_store) {
if (code_length_bitdepth[kStorageOrder[codes_to_store - 1]] != 0) {
break;
}
}
}
int skip_some = 0; // skips none.
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.
}
}
WriteBits(2, skip_some, storage_ix, storage);
for (int i = skip_some; i < codes_to_store; ++i) {
uint8_t l = code_length_bitdepth[kStorageOrder[i]];
WriteBits(kHuffmanBitLengthHuffmanCodeBitLengths[l],
kHuffmanBitLengthHuffmanCodeSymbols[l], storage_ix, storage);
}
}
void StoreHuffmanTreeToBitMask(
const std::vector<uint8_t> &huffman_tree,
const std::vector<uint8_t> &huffman_tree_extra_bits,
const uint8_t *code_length_bitdepth,
const std::vector<uint16_t> &code_length_bitdepth_symbols,
int * __restrict storage_ix,
uint8_t * __restrict storage) {
for (int i = 0; i < huffman_tree.size(); ++i) {
int ix = huffman_tree[i];
WriteBits(code_length_bitdepth[ix], code_length_bitdepth_symbols[ix],
storage_ix, storage);
// Extra bits
switch (ix) {
case 16:
WriteBits(2, huffman_tree_extra_bits[i], storage_ix, storage);
break;
case 17:
WriteBits(3, huffman_tree_extra_bits[i], storage_ix, storage);
break;
}
}
}
void StoreSimpleHuffmanTree(const uint8_t* depths,
int symbols[4],
int num_symbols,
int max_bits,
int *storage_ix, uint8_t *storage) {
// value of 1 indicates a simple Huffman code
WriteBits(2, 1, storage_ix, storage);
WriteBits(2, num_symbols - 1, storage_ix, storage); // NSYM - 1
// Sort
for (int i = 0; i < num_symbols; i++) {
for (int j = i + 1; j < num_symbols; j++) {
if (depths[symbols[j]] < depths[symbols[i]]) {
std::swap(symbols[j], symbols[i]);
}
}
}
if (num_symbols == 2) {
WriteBits(max_bits, symbols[0], storage_ix, storage);
WriteBits(max_bits, symbols[1], storage_ix, storage);
} else if (num_symbols == 3) {
WriteBits(max_bits, symbols[0], storage_ix, storage);
WriteBits(max_bits, symbols[1], storage_ix, storage);
WriteBits(max_bits, symbols[2], storage_ix, storage);
} else {
WriteBits(max_bits, symbols[0], storage_ix, storage);
WriteBits(max_bits, symbols[1], storage_ix, storage);
WriteBits(max_bits, symbols[2], storage_ix, storage);
WriteBits(max_bits, symbols[3], storage_ix, storage);
// tree-select
WriteBits(1, depths[symbols[0]] == 1 ? 1 : 0, storage_ix, storage);
}
}
// num = alphabet size
// depths = symbol depths
void StoreHuffmanTree(const uint8_t* depths, size_t num,
int *storage_ix, uint8_t *storage) {
// Write the Huffman tree into the brotli-representation.
std::vector<uint8_t> huffman_tree;
std::vector<uint8_t> huffman_tree_extra_bits;
// TODO: Consider allocating these from stack.
huffman_tree.reserve(256);
huffman_tree_extra_bits.reserve(256);
WriteHuffmanTree(depths, num, &huffman_tree, &huffman_tree_extra_bits);
// Calculate the statistics of the Huffman tree in brotli-representation.
int huffman_tree_histogram[kCodeLengthCodes] = { 0 };
for (int i = 0; i < huffman_tree.size(); ++i) {
++huffman_tree_histogram[huffman_tree[i]];
}
int num_codes = 0;
int code = 0;
for (int i = 0; i < kCodeLengthCodes; ++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.
// TODO: Consider allocating these from stack.
uint8_t code_length_bitdepth[kCodeLengthCodes] = { 0 };
std::vector<uint16_t> code_length_bitdepth_symbols(kCodeLengthCodes);
CreateHuffmanTree(&huffman_tree_histogram[0], kCodeLengthCodes,
5, &code_length_bitdepth[0]);
ConvertBitDepthsToSymbols(code_length_bitdepth, kCodeLengthCodes,
code_length_bitdepth_symbols.data());
// Now, we have all the data, let's start storing it
StoreHuffmanTreeOfHuffmanTreeToBitMask(num_codes, code_length_bitdepth,
storage_ix, storage);
if (num_codes == 1) {
code_length_bitdepth[code] = 0;
}
// Store the real huffman tree now.
StoreHuffmanTreeToBitMask(huffman_tree,
huffman_tree_extra_bits,
&code_length_bitdepth[0],
code_length_bitdepth_symbols,
storage_ix, storage);
}
void BuildAndStoreHuffmanTree(const int *histogram,
const int length,
uint8_t* depth,
uint16_t* bits,
int* storage_ix,
uint8_t* storage) {
int count = 0;
int s4[4] = { 0 };
for (size_t i = 0; i < length; i++) {
if (histogram[i]) {
if (count < 4) {
s4[count] = i;
} else if (count > 4) {
break;
}
count++;
}
}
int max_bits_counter = length - 1;
int max_bits = 0;
while (max_bits_counter) {
max_bits_counter >>= 1;
++max_bits;
}
if (count <= 1) {
WriteBits(4, 1, storage_ix, storage);
WriteBits(max_bits, s4[0], storage_ix, storage);
return;
}
CreateHuffmanTree(histogram, length, 15, depth);
ConvertBitDepthsToSymbols(depth, length, bits);
if (count <= 4) {
StoreSimpleHuffmanTree(depth, s4, count, max_bits, storage_ix, storage);
} else {
StoreHuffmanTree(depth, length, storage_ix, storage);
}
}
int IndexOf(const std::vector<int>& v, int value) {
for (int i = 0; i < v.size(); ++i) {
if (v[i] == value) return i;
}
return -1;
}
void MoveToFront(std::vector<int>* v, int index) {
int value = (*v)[index];
for (int i = index; i > 0; --i) {
(*v)[i] = (*v)[i - 1];
}
(*v)[0] = value;
}
std::vector<int> MoveToFrontTransform(const std::vector<int>& v) {
if (v.empty()) return v;
std::vector<int> mtf(*std::max_element(v.begin(), v.end()) + 1);
for (int i = 0; i < mtf.size(); ++i) mtf[i] = i;
std::vector<int> result(v.size());
for (int i = 0; i < v.size(); ++i) {
int index = IndexOf(mtf, v[i]);
result[i] = index;
MoveToFront(&mtf, index);
}
return result;
}
// Finds runs of zeros in v_in and replaces them with a prefix code of the run
// length plus extra bits in *v_out and *extra_bits. Non-zero values in v_in 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.
void RunLengthCodeZeros(const std::vector<int>& v_in,
int* max_run_length_prefix,
std::vector<int>* v_out,
std::vector<int>* extra_bits) {
int max_reps = 0;
for (int i = 0; i < v_in.size();) {
for (; i < v_in.size() && v_in[i] != 0; ++i) ;
int reps = 0;
for (; i < v_in.size() && v_in[i] == 0; ++i) {
++reps;
}
max_reps = std::max(reps, max_reps);
}
int max_prefix = max_reps > 0 ? Log2Floor(max_reps) : 0;
*max_run_length_prefix = std::min(max_prefix, *max_run_length_prefix);
for (int i = 0; i < v_in.size();) {
if (v_in[i] != 0) {
v_out->push_back(v_in[i] + *max_run_length_prefix);
extra_bits->push_back(0);
++i;
} else {
int reps = 1;
for (uint32_t k = i + 1; k < v_in.size() && v_in[k] == 0; ++k) {
++reps;
}
i += reps;
while (reps) {
if (reps < (2 << *max_run_length_prefix)) {
int run_length_prefix = Log2Floor(reps);
v_out->push_back(run_length_prefix);
extra_bits->push_back(reps - (1 << run_length_prefix));
break;
} else {
v_out->push_back(*max_run_length_prefix);
extra_bits->push_back((1 << *max_run_length_prefix) - 1);
reps -= (2 << *max_run_length_prefix) - 1;
}
}
}
}
}
// Returns a maximum zero-run-length-prefix value such that run-length coding
// zeros in v with this maximum prefix value and then encoding the resulting
// histogram and entropy-coding v produces the least amount of bits.
int BestMaxZeroRunLengthPrefix(const std::vector<int>& v) {
int min_cost = std::numeric_limits<int>::max();
int best_max_prefix = 0;
for (int max_prefix = 0; max_prefix <= 16; ++max_prefix) {
std::vector<int> rle_symbols;
std::vector<int> extra_bits;
int max_run_length_prefix = max_prefix;
RunLengthCodeZeros(v, &max_run_length_prefix, &rle_symbols, &extra_bits);
if (max_run_length_prefix < max_prefix) break;
HistogramContextMap histogram;
for (int i = 0; i < rle_symbols.size(); ++i) {
histogram.Add(rle_symbols[i]);
}
int bit_cost = PopulationCost(histogram);
if (max_prefix > 0) {
bit_cost += 4;
}
for (int i = 1; i <= max_prefix; ++i) {
bit_cost += histogram.data_[i] * i; // extra bits
}
if (bit_cost < min_cost) {
min_cost = bit_cost;
best_max_prefix = max_prefix;
}
}
return best_max_prefix;
}
void EncodeContextMap(const std::vector<int>& context_map,
int num_clusters,
int* storage_ix, uint8_t* storage) {
StoreVarLenUint8(num_clusters - 1, storage_ix, storage);
if (num_clusters == 1) {
return;
}
std::vector<int> transformed_symbols = MoveToFrontTransform(context_map);
std::vector<int> rle_symbols;
std::vector<int> extra_bits;
int max_run_length_prefix = BestMaxZeroRunLengthPrefix(transformed_symbols);
RunLengthCodeZeros(transformed_symbols, &max_run_length_prefix,
&rle_symbols, &extra_bits);
HistogramContextMap symbol_histogram;
for (int i = 0; i < rle_symbols.size(); ++i) {
symbol_histogram.Add(rle_symbols[i]);
}
bool use_rle = max_run_length_prefix > 0;
WriteBits(1, use_rle, storage_ix, storage);
if (use_rle) {
WriteBits(4, max_run_length_prefix - 1, storage_ix, storage);
}
EntropyCodeContextMap symbol_code;
memset(symbol_code.depth_, 0, sizeof(symbol_code.depth_));
memset(symbol_code.bits_, 0, sizeof(symbol_code.bits_));
BuildAndStoreHuffmanTree(symbol_histogram.data_,
num_clusters + max_run_length_prefix,
symbol_code.depth_, symbol_code.bits_,
storage_ix, storage);
for (int i = 0; i < rle_symbols.size(); ++i) {
WriteBits(symbol_code.depth_[rle_symbols[i]],
symbol_code.bits_[rle_symbols[i]],
storage_ix, storage);
if (rle_symbols[i] > 0 && rle_symbols[i] <= max_run_length_prefix) {
WriteBits(rle_symbols[i], extra_bits[i], storage_ix, storage);
}
}
WriteBits(1, 1, storage_ix, storage); // use move-to-front
}
void StoreBlockSwitch(const BlockSplitCode& code,
const int block_ix,
int* storage_ix,
uint8_t* storage) {
if (block_ix > 0) {
int typecode = code.type_code[block_ix];
WriteBits(code.type_depths[typecode], code.type_bits[typecode],
storage_ix, storage);
}
int lencode = code.length_prefix[block_ix];
WriteBits(code.length_depths[lencode], code.length_bits[lencode],
storage_ix, storage);
WriteBits(code.length_nextra[block_ix], code.length_extra[block_ix],
storage_ix, storage);
}
void BuildAndStoreBlockSplitCode(const std::vector<int>& types,
const std::vector<int>& lengths,
const int num_types,
BlockSplitCode* code,
int* storage_ix,
uint8_t* storage) {
const int num_blocks = types.size();
std::vector<int> type_histo(num_types + 2);
std::vector<int> length_histo(26);
int last_type = 1;
int second_last_type = 0;
code->type_code.resize(num_blocks);
code->length_prefix.resize(num_blocks);
code->length_nextra.resize(num_blocks);
code->length_extra.resize(num_blocks);
code->type_depths.resize(num_types + 2);
code->type_bits.resize(num_types + 2);
code->length_depths.resize(26);
code->length_bits.resize(26);
for (int i = 0; i < num_blocks; ++i) {
int type = types[i];
int type_code = (type == last_type + 1 ? 1 :
type == second_last_type ? 0 :
type + 2);
second_last_type = last_type;
last_type = type;
code->type_code[i] = type_code;
if (i > 0) ++type_histo[type_code];
GetBlockLengthPrefixCode(lengths[i],
&code->length_prefix[i],
&code->length_nextra[i],
&code->length_extra[i]);
++length_histo[code->length_prefix[i]];
}
StoreVarLenUint8(num_types - 1, storage_ix, storage);
if (num_types > 1) {
BuildAndStoreHuffmanTree(&type_histo[0], num_types + 2,
&code->type_depths[0], &code->type_bits[0],
storage_ix, storage);
BuildAndStoreHuffmanTree(&length_histo[0], 26,
&code->length_depths[0], &code->length_bits[0],
storage_ix, storage);
StoreBlockSwitch(*code, 0, storage_ix, storage);
}
}
void StoreTrivialContextMap(int num_types,
int context_bits,
int* storage_ix,
uint8_t* storage) {
StoreVarLenUint8(num_types - 1, storage_ix, storage);
if (num_types > 1) {
int repeat_code = context_bits - 1;
int repeat_bits = (1 << repeat_code) - 1;
int alphabet_size = num_types + repeat_code;
std::vector<int> histogram(alphabet_size);
std::vector<uint8_t> depths(alphabet_size);
std::vector<uint16_t> bits(alphabet_size);
// Write RLEMAX.
WriteBits(1, 1, storage_ix, storage);
WriteBits(4, repeat_code - 1, storage_ix, storage);
histogram[repeat_code] = num_types;
histogram[0] = 1;
for (int i = context_bits; i < alphabet_size; ++i) {
histogram[i] = 1;
}
BuildAndStoreHuffmanTree(&histogram[0], alphabet_size,
&depths[0], &bits[0],
storage_ix, storage);
for (int i = 0; i < num_types; ++i) {
int code = (i == 0 ? 0 : i + context_bits - 1);
WriteBits(depths[code], bits[code], storage_ix, storage);
WriteBits(depths[repeat_code], bits[repeat_code], storage_ix, storage);
WriteBits(repeat_code, repeat_bits, storage_ix, storage);
}
// Write IMTF (inverse-move-to-front) bit.
WriteBits(1, 1, storage_ix, storage);
}
}
// Manages the encoding of one block category (literal, command or distance).
class BlockEncoder {
public:
BlockEncoder(int alphabet_size,
int num_block_types,
const std::vector<int>& block_types,
const std::vector<int>& block_lengths)
: alphabet_size_(alphabet_size),
num_block_types_(num_block_types),
block_types_(block_types),
block_lengths_(block_lengths),
block_ix_(0),
block_len_(block_lengths.empty() ? 0 : block_lengths[0]),
entropy_ix_(0) {}
// Creates entropy codes of block lengths and block types and stores them
// to the bit stream.
void BuildAndStoreBlockSwitchEntropyCodes(int* storage_ix, uint8_t* storage) {
BuildAndStoreBlockSplitCode(
block_types_, block_lengths_, num_block_types_,
&block_split_code_, storage_ix, storage);
}
// Creates entropy codes for all block types and stores them to the bit
// stream.
template<int kSize>
void BuildAndStoreEntropyCodes(
const std::vector<Histogram<kSize> >& histograms,
int* storage_ix, uint8_t* storage) {
depths_.resize(histograms.size() * alphabet_size_);
bits_.resize(histograms.size() * alphabet_size_);
for (int i = 0; i < histograms.size(); ++i) {
int ix = i * alphabet_size_;
BuildAndStoreHuffmanTree(&histograms[i].data_[0], alphabet_size_,
&depths_[ix], &bits_[ix],
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.
void StoreSymbol(int symbol, int* storage_ix, uint8_t* storage) {
if (block_len_ == 0) {
++block_ix_;
block_len_ = block_lengths_[block_ix_];
entropy_ix_ = block_types_[block_ix_] * alphabet_size_;
StoreBlockSwitch(block_split_code_, block_ix_, storage_ix, storage);
}
--block_len_;
int ix = entropy_ix_ + symbol;
WriteBits(depths_[ix], 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.
template<int kContextBits>
void StoreSymbolWithContext(int symbol, int context,
const std::vector<int>& context_map,
int* storage_ix, uint8_t* storage) {
if (block_len_ == 0) {
++block_ix_;
block_len_ = block_lengths_[block_ix_];
entropy_ix_ = block_types_[block_ix_] << kContextBits;
StoreBlockSwitch(block_split_code_, block_ix_, storage_ix, storage);
}
--block_len_;
int histo_ix = context_map[entropy_ix_ + context];
int ix = histo_ix * alphabet_size_ + symbol;
WriteBits(depths_[ix], bits_[ix], storage_ix, storage);
}
private:
const int alphabet_size_;
const int num_block_types_;
const std::vector<int>& block_types_;
const std::vector<int>& block_lengths_;
BlockSplitCode block_split_code_;
int block_ix_;
int block_len_;
int entropy_ix_;
std::vector<uint8_t> depths_;
std::vector<uint16_t> bits_;
};
void JumpToByteBoundary(int* storage_ix, uint8_t* storage) {
*storage_ix = (*storage_ix + 7) & ~7;
storage[*storage_ix >> 3] = 0;
}
bool StoreMetaBlock(const uint8_t* input,
size_t start_pos,
size_t length,
size_t mask,
uint8_t prev_byte,
uint8_t prev_byte2,
bool is_last,
int num_direct_distance_codes,
int distance_postfix_bits,
int literal_context_mode,
const brotli::Command *commands,
size_t n_commands,
const MetaBlockSplit& mb,
int *storage_ix,
uint8_t *storage) {
if (!StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage)) {
return false;
}
if (length == 0) {
// Only the last meta-block can be empty, so jump to next byte.
JumpToByteBoundary(storage_ix, storage);
return true;
}
int num_distance_codes =
kNumDistanceShortCodes + num_direct_distance_codes +
(48 << distance_postfix_bits);
BlockEncoder literal_enc(256,
mb.literal_split.num_types,
mb.literal_split.types,
mb.literal_split.lengths);
BlockEncoder command_enc(kNumCommandPrefixes,
mb.command_split.num_types,
mb.command_split.types,
mb.command_split.lengths);
BlockEncoder distance_enc(num_distance_codes,
mb.distance_split.num_types,
mb.distance_split.types,
mb.distance_split.lengths);
literal_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage);
command_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage);
distance_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage);
WriteBits(2, distance_postfix_bits, storage_ix, storage);
WriteBits(4, num_direct_distance_codes >> distance_postfix_bits,
storage_ix, storage);
for (int i = 0; i < mb.literal_split.num_types; ++i) {
WriteBits(2, literal_context_mode, storage_ix, storage);
}
if (mb.literal_context_map.empty()) {
StoreTrivialContextMap(mb.literal_histograms.size(), kLiteralContextBits,
storage_ix, storage);
} else {
EncodeContextMap(mb.literal_context_map, mb.literal_histograms.size(),
storage_ix, storage);
}
if (mb.distance_context_map.empty()) {
StoreTrivialContextMap(mb.distance_histograms.size(), kDistanceContextBits,
storage_ix, storage);
} else {
EncodeContextMap(mb.distance_context_map, mb.distance_histograms.size(),
storage_ix, storage);
}
literal_enc.BuildAndStoreEntropyCodes(mb.literal_histograms,
storage_ix, storage);
command_enc.BuildAndStoreEntropyCodes(mb.command_histograms,
storage_ix, storage);
distance_enc.BuildAndStoreEntropyCodes(mb.distance_histograms,
storage_ix, storage);
size_t pos = start_pos;
for (int i = 0; i < n_commands; ++i) {
const Command cmd = commands[i];
int cmd_code = cmd.cmd_prefix_;
int lennumextra = cmd.cmd_extra_ >> 48;
uint64_t lenextra = cmd.cmd_extra_ & 0xffffffffffffULL;
command_enc.StoreSymbol(cmd_code, storage_ix, storage);
WriteBits(lennumextra, lenextra, storage_ix, storage);
if (mb.literal_context_map.empty()) {
for (int j = 0; j < cmd.insert_len_; j++) {
literal_enc.StoreSymbol(input[pos & mask], storage_ix, storage);
++pos;
}
} else {
for (int j = 0; j < cmd.insert_len_; ++j) {
int context = Context(prev_byte, prev_byte2,
literal_context_mode);
int literal = input[pos & mask];
literal_enc.StoreSymbolWithContext<kLiteralContextBits>(
literal, context, mb.literal_context_map, storage_ix, storage);
prev_byte2 = prev_byte;
prev_byte = literal;
++pos;
}
}
pos += cmd.copy_len_;
if (cmd.copy_len_ > 0) {
prev_byte2 = input[(pos - 2) & mask];
prev_byte = input[(pos - 1) & mask];
if (cmd.cmd_prefix_ >= 128) {
int dist_code = cmd.dist_prefix_;
int distnumextra = cmd.dist_extra_ >> 24;
int distextra = cmd.dist_extra_ & 0xffffff;
if (mb.distance_context_map.empty()) {
distance_enc.StoreSymbol(dist_code, storage_ix, storage);
} else {
int context = cmd.DistanceContext();
distance_enc.StoreSymbolWithContext<kDistanceContextBits>(
dist_code, context, mb.distance_context_map, storage_ix, storage);
}
brotli::WriteBits(distnumextra, distextra, storage_ix, storage);
}
}
}
if (is_last) {
JumpToByteBoundary(storage_ix, storage);
}
return true;
}
// This is for storing uncompressed blocks (simple raw storage of
// bytes-as-bytes).
bool StoreUncompressedMetaBlock(bool final_block,
const uint8_t * __restrict input,
size_t position, size_t mask,
size_t len,
int * __restrict storage_ix,
uint8_t * __restrict storage) {
if (!brotli::StoreUncompressedMetaBlockHeader(len, storage_ix, storage)) {
return false;
}
JumpToByteBoundary(storage_ix, storage);
size_t masked_pos = position & mask;
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 WriteBits.
brotli::WriteBitsPrepareStorage(*storage_ix, storage);
// Since the uncomressed block itself may not be the final block, add an empty
// one after this.
if (final_block) {
brotli::WriteBits(1, 1, storage_ix, storage); // islast
brotli::WriteBits(1, 1, storage_ix, storage); // isempty
JumpToByteBoundary(storage_ix, storage);
}
return true;
}
void StoreSyncMetaBlock(int * __restrict storage_ix,
uint8_t * __restrict storage) {
// Empty metadata meta-block bit pattern:
// 1 bit: is_last (0)
// 2 bits: num nibbles (3)
// 1 bit: reserved (0)
// 2 bits: metadata length bytes (0)
WriteBits(6, 6, storage_ix, storage);
JumpToByteBoundary(storage_ix, storage);
}
} // namespace brotli
================================================
FILE: csrc/enc/brotli_bit_stream.h
================================================
// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// 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 <stddef.h>
#include <stdint.h>
#include <vector>
#include "./metablock.h"
namespace brotli {
// All Store functions here will use a storage_ix, which is always the bit
// position for the current storage.
// Stores a number between 0 and 255.
void StoreVarLenUint8(int n, int* storage_ix, uint8_t* storage);
// Stores the compressed meta-block header.
bool StoreCompressedMetaBlockHeader(bool final_block,
size_t length,
int* storage_ix,
uint8_t* storage);
// Stores the uncompressed meta-block header.
bool StoreUncompressedMetaBlockHeader(size_t length,
int* storage_ix,
uint8_t* storage);
// Stores a context map where the histogram type is always the block type.
void StoreTrivialContextMap(int num_types,
int context_bits,
int* storage_ix,
uint8_t* storage);
void StoreHuffmanTreeOfHuffmanTreeToBitMask(
const int num_codes,
const uint8_t *code_length_bitdepth,
int *storage_ix,
uint8_t *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.
void BuildAndStoreHuffmanTree(const int *histogram,
const int length,
uint8_t* depth,
uint16_t* bits,
int* storage_ix,
uint8_t* storage);
// Encodes the given context map to the bit stream. The number of different
// histogram ids is given by num_clusters.
void EncodeContextMap(const std::vector<int>& context_map,
int num_clusters,
int* storage_ix, uint8_t* storage);
// Data structure that stores everything that is needed to encode each block
// switch command.
struct BlockSplitCode {
std::vector<int> type_code;
std::vector<int> length_prefix;
std::vector<int> length_nextra;
std::vector<int> length_extra;
std::vector<uint8_t> type_depths;
std::vector<uint16_t> type_bits;
std::vector<uint8_t> length_depths;
std::vector<uint16_t> length_bits;
};
// 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.
void BuildAndStoreBlockSplitCode(const std::vector<int>& types,
const std::vector<int>& lengths,
const int num_types,
BlockSplitCode* code,
int* storage_ix,
uint8_t* storage);
// Stores the block switch command with index block_ix to the bit stream.
void StoreBlockSwitch(const BlockSplitCode& code,
const int block_ix,
int* storage_ix,
uint8_t* storage);
bool StoreMetaBlock(const uint8_t* input,
size_t start_pos,
size_t length,
size_t mask,
uint8_t prev_byte,
uint8_t prev_byte2,
bool final_block,
int num_direct_distance_codes,
int distance_postfix_bits,
int literal_context_mode,
const brotli::Command *commands,
size_t n_commands,
const MetaBlockSplit& mb,
int *storage_ix,
uint8_t *storage);
// This is for storing uncompressed blocks (simple raw storage of
// bytes-as-bytes).
bool StoreUncompressedMetaBlock(bool final_block,
const uint8_t* input,
size_t position, size_t mask,
size_t len,
int* storage_ix,
uint8_t* storage);
// Stores an empty metadata meta-block and syncs to a byte boundary.
void StoreSyncMetaBlock(int* storage_ix, uint8_t* storage);
} // namespace brotli
#endif // BROTLI_ENC_BROTLI_BIT_STREAM_H_
================================================
FILE: csrc/enc/cluster.h
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Functions for clustering similar histograms together.
#ifndef BROTLI_ENC_CLUSTER_H_
#define BROTLI_ENC_CLUSTER_H_
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <algorithm>
#include <complex>
#include <map>
#include <set>
#include <utility>
#include <vector>
#include "./bit_cost.h"
#include "./entropy_encode.h"
#include "./fast_log.h"
#include "./histogram.h"
namespace brotli {
struct HistogramPair {
int idx1;
int idx2;
bool valid;
double cost_combo;
double cost_diff;
};
struct HistogramPairComparator {
bool operator()(const HistogramPair& p1, const HistogramPair& p2) const {
if (p1.cost_diff != p2.cost_diff) {
return p1.cost_diff > p2.cost_diff;
}
return abs(p1.idx1 - p1.idx2) > abs(p2.idx1 - p2.idx2);
}
};
// Returns entropy reduction of the context map when we combine two clusters.
inline double ClusterCostDiff(int size_a, int size_b) {
int size_c = size_a + size_b;
return size_a * FastLog2(size_a) + size_b * FastLog2(size_b) -
size_c * FastLog2(size_c);
}
// 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 heap.
template<typename HistogramType>
void CompareAndPushToHeap(const HistogramType* out,
const int* cluster_size,
int idx1, int idx2,
std::vector<HistogramPair>* pairs) {
if (idx1 == idx2) {
return;
}
if (idx2 < idx1) {
int t = idx2;
idx2 = idx1;
idx1 = t;
}
bool store_pair = false;
HistogramPair p;
p.idx1 = idx1;
p.idx2 = idx2;
p.valid = true;
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_;
store_pair = true;
} else if (out[idx2].total_count_ == 0) {
p.cost_combo = out[idx1].bit_cost_;
store_pair = true;
} else {
double threshold = pairs->empty() ? 1e99 :
std::max(0.0, (*pairs)[0].cost_diff);
HistogramType combo = out[idx1];
combo.AddHistogram(out[idx2]);
double cost_combo = PopulationCost(combo);
if (cost_combo < threshold - p.cost_diff) {
p.cost_combo = cost_combo;
store_pair = true;
}
}
if (store_pair) {
p.cost_diff += p.cost_combo;
pairs->push_back(p);
std::push_heap(pairs->begin(), pairs->end(), HistogramPairComparator());
}
}
template<typename HistogramType>
void HistogramCombine(HistogramType* out,
int* cluster_size,
int* symbols,
int symbols_size,
int max_clusters) {
double cost_diff_threshold = 0.0;
int min_cluster_size = 1;
std::set<int> all_symbols;
std::vector<int> clusters;
for (int i = 0; i < symbols_size; ++i) {
if (all_symbols.find(symbols[i]) == all_symbols.end()) {
all_symbols.insert(symbols[i]);
clusters.push_back(symbols[i]);
}
}
// We maintain a heap of histogram pairs, ordered by the bit cost reduction.
std::vector<HistogramPair> pairs;
for (int idx1 = 0; idx1 < clusters.size(); ++idx1) {
for (int idx2 = idx1 + 1; idx2 < clusters.size(); ++idx2) {
CompareAndPushToHeap(out, cluster_size, clusters[idx1], clusters[idx2],
&pairs);
}
}
while (clusters.size() > min_cluster_size) {
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.
int best_idx1 = pairs[0].idx1;
int best_idx2 = pairs[0].idx2;
out[best_idx1].AddHistogram(out[best_idx2]);
out[best_idx1].bit_cost_ = pairs[0].cost_combo;
cluster_size[best_idx1] += cluster_size[best_idx2];
for (int i = 0; i < symbols_size; ++i) {
if (symbols[i] == best_idx2) {
symbols[i] = best_idx1;
}
}
for (int i = 0; i + 1 < clusters.size(); ++i) {
if (clusters[i] >= best_idx2) {
clusters[i] = clusters[i + 1];
}
}
clusters.pop_back();
// Invalidate pairs intersecting the just combined best pair.
for (int i = 0; i < pairs.size(); ++i) {
HistogramPair& p = pairs[i];
if (p.idx1 == best_idx1 || p.idx2 == best_idx1 ||
p.idx1 == best_idx2 || p.idx2 == best_idx2) {
p.valid = false;
}
}
// Pop invalid pairs from the top of the heap.
while (!pairs.empty() && !pairs[0].valid) {
std::pop_heap(pairs.begin(), pairs.end(), HistogramPairComparator());
pairs.pop_back();
}
// Push new pairs formed with the combined histogram to the heap.
for (int i = 0; i < clusters.size(); ++i) {
CompareAndPushToHeap(out, cluster_size, best_idx1, clusters[i], &pairs);
}
}
}
// -----------------------------------------------------------------------------
// Histogram refinement
// What is the bit cost of moving histogram from cur_symbol to candidate.
template<typename HistogramType>
double HistogramBitCostDistance(const HistogramType& histogram,
const HistogramType& candidate) {
if (histogram.total_count_ == 0) {
return 0.0;
}
HistogramType tmp = histogram;
tmp.AddHistogram(candidate);
return PopulationCost(tmp) - candidate.bit_cost_;
}
// Find the best 'out' histogram for each of the 'in' histograms.
// Note: we assume that out[]->bit_cost_ is already up-to-date.
template<typename HistogramType>
void HistogramRemap(const HistogramType* in, int in_size,
HistogramType* out, int* symbols) {
std::set<int> all_symbols;
for (int i = 0; i < in_size; ++i) {
all_symbols.insert(symbols[i]);
}
for (int i = 0; i < in_size; ++i) {
int best_out = i == 0 ? symbols[0] : symbols[i - 1];
double best_bits = HistogramBitCostDistance(in[i], out[best_out]);
for (std::set<int>::const_iterator k = all_symbols.begin();
k != all_symbols.end(); ++k) {
const double cur_bits = HistogramBitCostDistance(in[i], out[*k]);
if (cur_bits < best_bits) {
best_bits = cur_bits;
best_out = *k;
}
}
symbols[i] = best_out;
}
// Recompute each out based on raw and symbols.
for (std::set<int>::const_iterator k = all_symbols.begin();
k != all_symbols.end(); ++k) {
out[*k].Clear();
}
for (int i = 0; i < in_size; ++i) {
out[symbols[i]].AddHistogram(in[i]);
}
}
// Reorder histograms in *out so that the new symbols in *symbols come in
// increasing order.
template<typename HistogramType>
void HistogramReindex(std::vector<HistogramType>* out,
std::vector<int>* symbols) {
std::vector<HistogramType> tmp(*out);
std::map<int, int> new_index;
int next_index = 0;
for (int i = 0; i < symbols->size(); ++i) {
if (new_index.find((*symbols)[i]) == new_index.end()) {
new_index[(*symbols)[i]] = next_index;
(*out)[next_index] = tmp[(*symbols)[i]];
++next_index;
}
}
out->resize(next_index);
for (int i = 0; i < symbols->size(); ++i) {
(*symbols)[i] = new_index[(*symbols)[i]];
}
}
template<typename HistogramType>
void ClusterHistogramsTrivial(const std::vector<HistogramType>& in,
int num_contexts, int num_blocks,
int max_histograms,
std::vector<HistogramType>* out,
std::vector<int>* histogram_symbols) {
out->resize(num_blocks);
for (int i = 0; i < num_blocks; ++i) {
(*out)[i].Clear();
for (int j = 0; j < num_contexts; ++j) {
(*out)[i].AddHistogram(in[i * num_contexts + j]);
histogram_symbols->push_back(i);
}
}
}
// Clusters similar histograms in 'in' together, the selected histograms are
// placed in 'out', and for each index in 'in', *histogram_symbols will
// indicate which of the 'out' histograms is the best approximation.
template<typename HistogramType>
void ClusterHistograms(const std::vector<HistogramType>& in,
int num_contexts, int num_blocks,
int max_histograms,
std::vector<HistogramType>* out,
std::vector<int>* histogram_symbols) {
const int in_size = num_contexts * num_blocks;
std::vector<int> cluster_size(in_size, 1);
out->resize(in_size);
histogram_symbols->resize(in_size);
for (int i = 0; i < in_size; ++i) {
(*out)[i] = in[i];
(*out)[i].bit_cost_ = PopulationCost(in[i]);
(*histogram_symbols)[i] = i;
}
// Collapse similar histograms within a block type.
if (num_contexts > 1) {
for (int i = 0; i < num_blocks; ++i) {
HistogramCombine(&(*out)[0], &cluster_size[0],
&(*histogram_symbols)[i * num_contexts], num_contexts,
max_histograms);
}
}
// Collapse similar histograms.
HistogramCombine(&(*out)[0], &cluster_size[0],
&(*histogram_symbols)[0], in_size,
max_histograms);
// Find the optimal map from original histograms to the final ones.
HistogramRemap(&in[0], in_size, &(*out)[0], &(*histogram_symbols)[0]);
// Convert the context map to a canonical form.
HistogramReindex(out, histogram_symbols);
}
} // namespace brotli
#endif // BROTLI_ENC_CLUSTER_H_
================================================
FILE: csrc/enc/command.h
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This class models a sequence of literals and a backward reference copy.
#ifndef BROTLI_ENC_COMMAND_H_
#define BROTLI_ENC_COMMAND_H_
#include <stdint.h>
#include "./fast_log.h"
namespace brotli {
static inline void GetDistCode(int distance_code,
uint16_t* code, uint32_t* extra) {
distance_code -= 1;
if (distance_code < 16) {
*code = distance_code;
*extra = 0;
} else {
distance_code -= 12;
int numextra = Log2FloorNonZero(distance_code) - 1;
int prefix = distance_code >> numextra;
*code = 12 + 2 * numextra + prefix;
*extra = (numextra << 24) | (distance_code - (prefix << numextra));
}
}
static int insbase[] = { 0, 1, 2, 3, 4, 5, 6, 8, 10, 14, 18, 26, 34, 50, 66,
98, 130, 194, 322, 578, 1090, 2114, 6210, 22594 };
static int insextra[] = { 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5,
5, 6, 7, 8, 9, 10, 12, 14, 24 };
static int copybase[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 18, 22, 30, 38,
54, 70, 102, 134, 198, 326, 582, 1094, 2118 };
static int copyextra[] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4,
4, 5, 5, 6, 7, 8, 9, 10, 24 };
static inline int GetInsertLengthCode(int insertlen) {
if (insertlen < 6) {
return insertlen;
} else if (insertlen < 130) {
insertlen -= 2;
int nbits = Log2FloorNonZero(insertlen) - 1;
return (nbits << 1) + (insertlen >> nbits) + 2;
} else if (insertlen < 2114) {
return Log2FloorNonZero(insertlen - 66) + 10;
} else if (insertlen < 6210) {
return 21;
} else if (insertlen < 22594) {
return 22;
} else {
return 23;
}
}
static inline int GetCopyLengthCode(int copylen) {
if (copylen < 10) {
return copylen - 2;
} else if (copylen < 134) {
copylen -= 6;
int nbits = Log2FloorNonZero(copylen) - 1;
return (nbits << 1) + (copylen >> nbits) + 4;
} else if (copylen < 2118) {
return Log2FloorNonZero(copylen - 70) + 12;
} else {
return 23;
}
}
static inline int CombineLengthCodes(
int inscode, int copycode, int distancecode) {
int bits64 = (copycode & 0x7u) | ((inscode & 0x7u) << 3);
if (distancecode == 0 && inscode < 8 && copycode < 16) {
return (copycode < 8) ? bits64 : (bits64 | 64);
} else {
// "To convert an insert-and-copy length code to an insert length code and
// a copy length code, the following table can be used"
static const int cells[9] = { 2, 3, 6, 4, 5, 8, 7, 9, 10 };
return (cells[(copycode >> 3) + 3 * (inscode >> 3)] << 6) | bits64;
}
}
static inline void GetLengthCode(int insertlen, int copylen, int distancecode,
uint16_t* code, uint64_t* extra) {
int inscode = GetInsertLengthCode(insertlen);
int copycode = GetCopyLengthCode(copylen);
uint64_t insnumextra = insextra[inscode];
uint64_t numextra = insnumextra + copyextra[copycode];
uint64_t insextraval = insertlen - insbase[inscode];
uint64_t copyextraval = copylen - copybase[copycode];
*code = CombineLengthCodes(inscode, copycode, distancecode);
*extra = (numextra << 48) | (copyextraval << insnumextra) | insextraval;
}
struct Command {
Command() {}
Command(int insertlen, int copylen, int copylen_code, int distance_code)
: insert_len_(insertlen), copy_len_(copylen) {
GetDistCode(distance_code, &dist_prefix_, &dist_extra_);
GetLengthCode(insertlen, copylen_code, dist_prefix_,
&cmd_prefix_, &cmd_extra_);
}
Command(int insertlen)
: insert_len_(insertlen), copy_len_(0), dist_prefix_(16), dist_extra_(0) {
GetLengthCode(insertlen, 4, dist_prefix_, &cmd_prefix_, &cmd_extra_);
}
int DistanceCode() const {
if (dist_prefix_ < 16) {
return dist_prefix_ + 1;
}
int nbits = dist_extra_ >> 24;
int extra = dist_extra_ & 0xffffff;
int prefix = dist_prefix_ - 12 - 2 * nbits;
return (prefix << nbits) + extra + 13;
}
int DistanceContext() const {
int r = cmd_prefix_ >> 6;
int c = cmd_prefix_ & 7;
if ((r == 0 || r == 2 || r == 4 || r == 7) && (c <= 2)) {
return c;
}
return 3;
}
int insert_len_;
int copy_len_;
uint16_t cmd_prefix_;
uint16_t dist_prefix_;
uint64_t cmd_extra_;
uint32_t dist_extra_;
};
} // namespace brotli
#endif // BROTLI_ENC_COMMAND_H_
================================================
FILE: csrc/enc/context.h
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Functions to map previous bytes into a context id.
#ifndef BROTLI_ENC_CONTEXT_H_
#define BROTLI_ENC_CONTEXT_H_
#include <stdint.h>
namespace brotli {
// Second-order context lookup table for UTF8 byte streams.
//
// If p1 and p2 are the previous two bytes, we calcualte the context as
//
// context = kUTF8ContextLookup[p1] | kUTF8ContextLookup[p2 + 256].
//
// 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 | |
// |-------------|-------------------|---------------------|------------------|
static const uint8_t kUTF8ContextLookup[512] = {
// 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,
// 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 lookup table for small signed integers.
static const uint8_t kSigned3BitContextLookup[] = {
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,
};
enum ContextType {
CONTEXT_LSB6 = 0,
CONTEXT_MSB6 = 1,
CONTEXT_UTF8 = 2,
CONTEXT_SIGNED = 3
};
static inline uint8_t Context(uint8_t p1, uint8_t p2, int mode) {
switch (mode) {
case CONTEXT_LSB6:
return p1 & 0x3f;
case CONTEXT_MSB6:
return p1 >> 2;
case CONTEXT_UTF8:
return kUTF8ContextLookup[p1] | kUTF8ContextLookup[p2 + 256];
case CONTEXT_SIGNED:
return (kSigned3BitContextLookup[p1] << 3) + kSigned3BitContextLookup[p2];
default:
return 0;
}
}
} // namespace brotli
#endif // BROTLI_ENC_CONTEXT_H_
================================================
FILE: csrc/enc/dictionary.h
================================================
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Collection of static dictionary words.
#ifndef BROTLI_ENC_DICTIONARY_H_
#define BROTLI_ENC_DICTIONARY_H_
#include <stdint.h>
static const uint8_t kBrotliDictionary[] = {
0x74, 0x69, 0x6d, 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x66, 0x65, 0x6c,
0x65, 0x66, 0x74, 0x62, 0x61, 0x63, 0x6b, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x61,
0x74, 0x61, 0x73, 0x68, 0x6f, 0x77, 0x6f, 0x6e, 0x6c, 0x79, 0x73, 0x69, 0x74,
0x65, 0x63, 0x69, 0x74, 0x79, 0x6f, 0x70, 0x65, 0x6e, 0x6a, 0x75, 0x73, 0x74,
0x6c, 0x69, 0x6b, 0x65, 0x66, 0x72, 0x65, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x74,
0x65, 0x78, 0x74, 0x79, 0x65, 0x61, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x62, 0x6f,
0x64, 0x79, 0x6c, 0x6f, 0x76, 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x62, 0x6f, 0x6f,
0x6b, 0x70, 0x6c, 0x61, 0x79, 0x6c, 0x69, 0x76, 0x65, 0x6c, 0x69, 0x6e, 0x65,
0x68, 0x65, 0x6c, 0x70, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x64, 0x65, 0x6d,
0x6f, 0x72, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x6c, 0x6f, 0x6e, 0x67, 0x74, 0x68,
0x65, 0x6d, 0x76, 0x69, 0x65, 0x77, 0x66, 0x69, 0x6e, 0x64, 0x70, 0x61, 0x67,
0x65, 0x64, 0x61, 0x79, 0x73, 0x66, 0x75, 0x6c, 0x6c, 0x68, 0x65, 0x61, 0x64,
0x74, 0x65, 0x72, 0x6d, 0x65, 0x61, 0x63, 0x68, 0x61, 0x72, 0x65, 0x61, 0x66,
0x72, 0x6f, 0x6d, 0x74, 0x72, 0x75, 0x65, 0x6d, 0x61, 0x72, 0x6b, 0x61, 0x62,
0x6c, 0x65, 0x75, 0x70, 0x6f, 0x6e, 0x68, 0x69, 0x67, 0x68, 0x64, 0x61, 0x74,
0x65, 0x6c, 0x61, 0x6e, 0x64, 0x6e, 0x65, 0x77, 0x73, 0x65, 0x76, 0x65, 0x6e,
0x6e, 0x65, 0x78, 0x74, 0x63, 0x61, 0x73, 0x65, 0x62, 0x6f, 0x74, 0x68, 0x70,
0x6f, 0x73, 0x74, 0x75, 0x73, 0x65, 0x64, 0x6d, 0x61, 0x64, 0x65, 0x68, 0x61,
0x6e, 0x64, 0x68, 0x65, 0x72, 0x65, 0x77, 0x68, 0x61, 0x74, 0x6e, 0x61, 0x6d,
0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x62, 0x6c, 0x6f, 0x67, 0x73, 0x69, 0x7a, 0x65,
0x62, 0x61, 0x73, 0x65, 0x68, 0x65, 0x6c, 0x64, 0x6d, 0x61, 0x6b, 0x65, 0x6d,
0x61, 0x69, 0x6e, 0x75, 0x73, 0x65, 0x72, 0x27, 0x29, 0x20, 0x2b, 0x68, 0x6f,
0x6c, 0x64, 0x65, 0x6e, 0x64, 0x73, 0x77, 0x69, 0x74, 0x68, 0x4e, 0x65, 0x77,
0x73, 0x72, 0x65, 0x61, 0x64, 0x77, 0x65, 0x72, 0x65, 0x73, 0x69, 0x67, 0x6e,
0x74, 0x61, 0x6b, 0x65, 0x68, 0x61, 0x76, 0x65, 0x67, 0x61, 0x6d, 0x65, 0x73,
0x65, 0x65, 0x6e, 0x63, 0x61, 0x6c, 0x6c, 0x70, 0x61, 0x74, 0x68, 0x77, 0x65,
0x6c, 0x6c, 0x70, 0x6c, 0x75, 0x73, 0x6d, 0x65, 0x6e, 0x75, 0x66, 0x69, 0x6c,
0x6d, 0x70, 0x61, 0x72, 0x74, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x68, 0x69, 0x73,
0x6c, 0x69, 0x73, 0x74, 0x67, 0x6f, 0x6f, 0x64, 0x6e, 0x65, 0x65, 0x64, 0x77,
0x61, 0x79, 0x73, 0x77, 0x65, 0x73, 0x74, 0x6a, 0x6f, 0x62, 0x73, 0x6d, 0x69,
0x6e, 0x64, 0x61, 0x6c, 0x73, 0x6f, 0x6c, 0x6f, 0x67, 0x6f, 0x72, 0x69, 0x63,
0x68, 0x75, 0x73, 0x65, 0x73, 0x6c, 0x61, 0x73, 0x74, 0x74, 0x65, 0x61, 0x6d,
0x61, 0x72, 0x6d, 0x79, 0x66, 0x6f, 0x6f, 0x64, 0x6b, 0x69, 0x6e, 0x67, 0x77,
0x69, 0x6c, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x77, 0x61, 0x72, 0x64, 0x62, 0x65,
0x73, 0x74, 0x66, 0x69, 0x72, 0x65, 0x50, 0x61, 0x67, 0x65, 0x6b, 0x6e, 0x6f,
0x77, 0x61, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x6e, 0x67, 0x6d, 0x6f, 0x76, 0x65,
0x74, 0x68, 0x61, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x67, 0x69, 0x76, 0x65, 0x73,
0x65, 0x6c, 0x66, 0x6e, 0x6f, 0x74, 0x65, 0x6d, 0x75, 0x63, 0x68, 0x66, 0x65,
0x65, 0x64, 0x6d, 0x61, 0x6e, 0x79, 0x72, 0x6f, 0x63, 0x6b, 0x69, 0x63, 0x6f,
0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x6c, 0x6f, 0x6f, 0x6b, 0x68, 0x69, 0x64, 0x65,
0x64, 0x69, 0x65, 0x64, 0x48, 0x6f, 0x6d, 0x65, 0x72, 0x75, 0x6c, 0x65, 0x68,
0x6f, 0x73, 0x74, 0x61, 0x6a, 0x61, 0x78, 0x69, 0x6e, 0x66, 0x6f, 0x63, 0x6c,
0x75, 0x62, 0x6c, 0x61, 0x77, 0x73, 0x6c, 0x65, 0x73, 0x73, 0x68, 0x61, 0x6c,
0x66, 0x73, 0x6f, 0x6d, 0x65, 0x73, 0x75, 0x63, 0x68, 0x7a, 0x6f, 0x6e, 0x65,
0x31, 0x30, 0x30, 0x25, 0x6f, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x72, 0x65, 0x54,
0x69, 0x6d, 0x65, 0x72, 0x61, 0x63, 0x65, 0x62, 0x6c, 0x75, 0x65, 0x66, 0x6f,
0x75, 0x72, 0x77, 0x65, 0x65, 0x6b, 0x66, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x70,
0x65, 0x67, 0x61, 0x76, 0x65, 0x68, 0x61, 0x72, 0x64, 0x6c, 0x6f, 0x73, 0x74,
0x77, 0x68, 0x65, 0x6e, 0x70, 0x61, 0x72, 0x6b, 0x6b, 0x65, 0x70, 0x74, 0x70,
0x61, 0x73, 0x73, 0x73, 0x68, 0x69, 0x70, 0x72, 0x6f, 0x6f, 0x6d, 0x48, 0x54,
0x4d, 0x4c, 0x70, 0x6c, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x64, 0x6f, 0x6e,
0x65, 0x73, 0x61, 0x76, 0x65, 0x6b, 0x65, 0x65, 0x70, 0x66, 0x6c, 0x61, 0x67,
0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x6f, 0x6c, 0x64, 0x66, 0x69, 0x76, 0x65, 0x74,
0x6f, 0x6f, 0x6b, 0x72, 0x61, 0x74, 0x65, 0x74, 0x6f, 0x77, 0x6e, 0x6a, 0x75,
0x6d, 0x70, 0x74, 0x68, 0x75, 0x73, 0x64, 0x61, 0x72, 0x6b, 0x63, 0x61, 0x72,
0x64, 0x66, 0x69, 0x6c, 0x65, 0x66, 0x65, 0x61, 0x72, 0x73, 0x74, 0x61, 0x79,
0x6b, 0x69, 0x6c, 0x6c, 0x74, 0x68, 0x61, 0x74, 0x66, 0x61, 0x6c, 0x6c, 0x61,
0x75, 0x74, 0x6f, 0x65, 0x76, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x74, 0x61,
0x6c, 0x6b, 0x73, 0x68, 0x6f, 0x70, 0x76, 0x6f, 0x74, 0x65, 0x64, 0x65, 0x65,
0x70, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x65, 0x73, 0x74, 0x74, 0x75, 0x72, 0x6e,
0x62, 0x6f, 0x72, 0x6e, 0x62, 0x61, 0x6e, 0x64, 0x66, 0x65, 0x6c, 0x6c, 0x72,
0x6f, 0x73, 0x65, 0x75, 0x72, 0x6c, 0x28, 0x73, 0x6b, 0x69, 0x6e, 0x72, 0x6f,
0x6c, 0x65, 0x63, 0x6f, 0x6d, 0x65, 0x61, 0x63, 0x74, 0x73, 0x61, 0x67, 0x65,
0x73, 0x6d, 0x65, 0x65, 0x74, 0x67, 0x6f, 0x6c, 0x64, 0x2e, 0x6a, 0x70, 0x67,
0x69, 0x74, 0x65, 0x6d, 0x76, 0x61, 0x72, 0x79, 0x66, 0x65, 0x6c, 0x74, 0x74,
0x68, 0x65, 0x6e, 0x73, 0x65, 0x6e, 0x64, 0x64, 0x72, 0x6f, 0x70, 0x56, 0x69,
0x65, 0x77, 0x63, 0x6f, 0x70, 0x79, 0x31, 0x2e, 0x30, 0x22, 0x3c, 0x2f, 0x61,
0x3e, 0x73, 0x74, 0x6f, 0x70, 0x65, 0x6c, 0x73, 0x65, 0x6c, 0x69, 0x65, 0x73,
0x74, 0x6f, 0x75, 0x72, 0x70, 0x61, 0x63, 0x6b, 0x2e, 0x67, 0x69, 0x66, 0x70,
0x61, 0x73, 0x74, 0x63, 0x73, 0x73, 0x3f, 0x67, 0x72, 0x61, 0x79, 0x6d, 0x65,
0x61, 0x6e, 0x26, 0x67, 0x74, 0x3b, 0x72, 0x69, 0x64, 0x65, 0x73, 0x68, 0x6f,
0x74, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x61, 0x69, 0x64, 0x72, 0x6f, 0x61, 0x64,
0x76, 0x61, 0x72, 0x20, 0x66, 0x65, 0x65, 0x6c, 0x6a, 0x6f, 0x68, 0x6e, 0x72,
0x69, 0x63, 0x6b, 0x70, 0x6f, 0x72, 0x74, 0x66, 0x61, 0x73, 0x74, 0x27, 0x55,
0x41, 0x2d, 0x64, 0x65, 0x61, 0x64, 0x3c, 0x2f, 0x62, 0x3e, 0x70, 0x6f, 0x6f,
0x72, 0x62, 0x69, 0x6c, 0x6c, 0x74, 0x79, 0x70, 0x65, 0x55, 0x2e, 0x53, 0x2e,
0x77, 0x6f, 0x6f, 0x64, 0x6d, 0x75, 0x73, 0x74, 0x32, 0x70, 0x78, 0x3b, 0x49,
0x6e, 0x66, 0x6f, 0x72, 0x61, 0x6e, 0x6b, 0x77, 0x69, 0x64, 0x65, 0x77, 0x61,
0x6e, 0x74, 0x77, 0x61, 0x6c, 0x6c, 0x6c, 0x65, 0x61, 0x64, 0x5b, 0x30, 0x5d,
0x3b, 0x70, 0x61, 0x75, 0x6c, 0x77, 0x61, 0x76, 0x65, 0x73, 0x75, 0x72, 0x65,
0x24, 0x28, 0x27, 0x23, 0x77, 0x61, 0x69, 0x74, 0x6d, 0x61, 0x73, 0x73, 0x61,
0x72, 0x6d, 0x73, 0x67, 0x6f, 0x65, 0x73, 0x67, 0x61, 0x69, 0x6e, 0x6c, 0x61,
0x6e, 0x67, 0x70, 0x61, 0x69, 0x64, 0x21, 0x2d, 0x2d, 0x20, 0x6c, 0x6f, 0x63,
0x6b, 0x75, 0x6e, 0x69, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x77, 0x61, 0x6c, 0x6b,
0x66, 0x69, 0x72, 0x6d, 0x77, 0x69, 0x66, 0x65, 0x78, 0x6d, 0x6c, 0x22, 0x73,
0x6f, 0x6e, 0x67, 0x74, 0x65, 0x73, 0x74, 0x32, 0x30, 0x70, 0x78, 0x6b, 0x69,
0x6e, 0x64, 0x72, 0x6f, 0x77, 0x73, 0x74, 0x6f, 0x6f, 0x6c, 0x66, 0x6f, 0x6e,
0x74, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x66, 0x65, 0x73, 0x74, 0x61, 0x72,
0x6d, 0x61, 0x70, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x72, 0x61, 0x69, 0x6e, 0x66,
0x6c, 0x6f, 0x77, 0x62, 0x61, 0x62, 0x79, 0x73, 0x70, 0x61, 0x6e, 0x73, 0x61,
0x79, 0x73, 0x34, 0x70, 0x78, 0x3b, 0x36, 0x70, 0x78, 0x3b, 0x61, 0x72, 0x74,
0x73, 0x66, 0x6f, 0x6f, 0x74, 0x72, 0x65, 0x61, 0x6c, 0x77, 0x69, 0x6b, 0x69,
0x68, 0x65, 0x61, 0x74, 0x73, 0x74, 0x65, 0x70, 0x74, 0x72, 0x69, 0x70, 0x6f,
0x72, 0x67, 0x2f, 0x6c, 0x61, 0x6b, 0x65, 0x77, 0x65, 0x61, 0x6b, 0x74, 0x6f,
0x6c, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x63, 0x61, 0x73, 0x74, 0x66, 0x61, 0x6e,
0x73, 0x62, 0x61, 0x6e, 0x6b, 0x76, 0x65, 0x72, 0x79, 0x72, 0x75, 0x6e, 0x73,
0x6a, 0x75, 0x6c, 0x79, 0x74, 0x61, 0x73, 0x6b, 0x31, 0x70, 0x78, 0x3b, 0x67,
0x6f, 0x61, 0x6c, 0x67, 0x72, 0x65, 0x77, 0x73, 0x6c, 0x6f, 0x77, 0x65, 0x64,
0x67, 0x65, 0x69, 0x64, 0x3d, 0x22, 0x73, 0x65, 0x74, 0x73, 0x35, 0x70, 0x78,
0x3b, 0x2e, 0x6a, 0x73, 0x3f, 0x34, 0x30, 0x70, 0x78, 0x69, 0x66, 0x20, 0x28,
0x73, 0x6f, 0x6f, 0x6e, 0x73, 0x65, 0x61, 0x74, 0x6e, 0x6f, 0x6e, 0x65, 0x74,
0x75, 0x62, 0x65, 0x7a, 0x65, 0x72, 0x6f, 0x73, 0x65, 0x6e, 0x74, 0x72, 0x65,
0x65, 0x64, 0x66, 0x61, 0x63, 0x74, 0x69, 0x6e, 0x74, 0x6f, 0x67, 0x69, 0x66,
0x74, 0x68, 0x61, 0x72, 0x6d, 0x31, 0x38, 0x70, 0x78, 0x63, 0x61, 0x6d, 0x65,
0x68, 0x69, 0x6c, 0x6c, 0x62, 0x6f, 0x6c, 0x64, 0x7a, 0x6f, 0x6f, 0x6d, 0x76,
0x6f, 0x69, 0x64, 0x65, 0x61, 0x73, 0x79, 0x72, 0x69, 0x6e, 0x67, 0x66, 0x69,
0x6c, 0x6c, 0x70, 0x65, 0x61, 0x6b, 0x69, 0x6e, 0x69, 0x74, 0x63, 0x6f, 0x73,
0x74, 0x33, 0x70, 0x78, 0x3b, 0x6a, 0x61, 0x63, 0x6b, 0x74, 0x61, 0x67, 0x73,
0x62, 0x69, 0x74, 0x73, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x64, 0x69, 0x74, 0x6b,
0x6e, 0x65, 0x77, 0x6e, 0x65, 0x61, 0x72, 0x3c, 0x21, 0x2d, 0x2d, 0x67, 0x72,
0x6f, 0x77, 0x4a, 0x53, 0x4f, 0x4e, 0x64, 0x75, 0x74, 0x79, 0x4e, 0x61, 0x6d,
0x65, 0x73, 0x61, 0x6c, 0x65, 0x79, 0x6f, 0x75, 0x20, 0x6c, 0x6f, 0x74, 0x73,
0x70, 0x61, 0x69, 0x6e, 0x6a, 0x61, 0x7a, 0x7a, 0x63, 0x6f, 0x6c, 0x64, 0x65,
0x79, 0x65, 0x73, 0x66, 0x69, 0x73, 0x68, 0x77, 0x77, 0x77, 0x2e, 0x72, 0x69,
0x73, 0x6b, 0x74, 0x61, 0x62, 0x73, 0x70, 0x72, 0x65, 0x76, 0x31, 0x30, 0x70,
0x78, 0x72, 0x69, 0x73, 0x65, 0x32, 0x35, 0x70, 0x78, 0x42, 0x6c, 0x75, 0x65,
0x64, 0x69, 0x6e, 0x67, 0x33, 0x30, 0x30, 0x2c, 0x62, 0x61, 0x6c, 0x6c, 0x66,
0x6f, 0x72, 0x64, 0x65, 0x61, 0x72, 0x6e, 0x77, 0x69, 0x6c, 0x64, 0x62, 0x6f,
0x78, 0x2e, 0x66, 0x61, 0x69, 0x72, 0x6c, 0x61, 0x63, 0x6b, 0x76, 0x65, 0x72,
0x73, 0x70, 0x61, 0x69, 0x72, 0x6a, 0x75, 0x6e, 0x65, 0x74, 0x65, 0x63, 0x68,
0x69, 0x66, 0x28, 0x21, 0x70, 0x69, 0x63, 0x6b, 0x65, 0x76, 0x69, 0x6c, 0x24,
0x28, 0x22, 0x23, 0x77, 0x61, 0x72, 0x6d, 0x6c, 0x6f, 0x72, 0x64, 0x64, 0x6f,
0x65, 0x73, 0x70, 0x75, 0x6c, 0x6c, 0x2c, 0x30, 0x30, 0x30, 0x69, 0x64, 0x65,
0x61, 0x64, 0x72, 0x61, 0x77, 0x68, 0x75, 0x67, 0x65, 0x73, 0x70, 0x6f, 0x74,
0x66, 0x75, 0x6e, 0x64, 0x62, 0x75, 0x72, 0x6e, 0x68, 0x72, 0x65, 0x66, 0x63,
0x65, 0x6c, 0x6c, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x68, 0x6f,
0x75, 0x72, 0x6c, 0x6f, 0x73, 0x73, 0x66, 0x75, 0x65, 0x6c, 0x31, 0x32, 0x70,
0x78, 0x73, 0x75, 0x69, 0x74, 0x64, 0x65, 0x61, 0x6c, 0x52, 0x53, 0x53, 0x22,
0x61, 0x67, 0x65, 0x64, 0x67, 0x72, 0x65, 0x79, 0x47, 0x45, 0x54, 0x22, 0x65,
0x61, 0x73, 0x65, 0x61, 0x69, 0x6d, 0x73, 0x67, 0x69, 0x72, 0x6c, 0x61, 0x69,
0x64, 0x73, 0x38, 0x70, 0x78, 0x3b, 0x6e, 0x61, 0x76, 0x79, 0x67, 0x72, 0x69,
0x64, 0x74, 0x69, 0x70, 0x73, 0x23, 0x39, 0x39, 0x39, 0x77, 0x61, 0x72, 0x73,
0x6c, 0x61, 0x64, 0x79, 0x63, 0x61, 0x72, 0x73, 0x29, 0x3b, 0x20, 0x7d, 0x70,
0x68, 0x70, 0x3f, 0x68, 0x65, 0x6c, 0x6c, 0x74, 0x61, 0x6c, 0x6c, 0x77, 0x68,
0x6f, 0x6d, 0x7a, 0x68, 0x3a, 0xe5, 0x2a, 0x2f, 0x0d, 0x0a, 0x20, 0x31, 0x30,
0x30, 0x68, 0x61, 0x6c, 0x6c, 0x2e, 0x0a, 0x0a, 0x41, 0x37, 0x70, 0x78, 0x3b,
0x70, 0x75, 0x73, 0x68, 0x63, 0x68, 0x61, 0x74, 0x30, 0x70, 0x78, 0x3b, 0x63,
0x72, 0x65, 0x77, 0x2a, 0x2f, 0x3c, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x37, 0x35,
0x70, 0x78, 0x66, 0x6c, 0x61, 0x74, 0x72, 0x61, 0x72, 0x65, 0x20, 0x26, 0x26,
0x20, 0x74, 0x65, 0x6c, 0x6c, 0x63, 0x61, 0x6d, 0x70, 0x6f, 0x6e, 0x74, 0x6f,
0x6c, 0x61, 0x69, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x73, 0x6b, 0x69, 0x70, 0x74,
0x65, 0x6e, 0x74, 0x66, 0x69, 0x6e, 0x65, 0x6d, 0x61, 0x6c, 0x65, 0x67, 0x65,
0x74, 0x73, 0x70, 0x6c, 0x6f, 0x74, 0x34, 0x30, 0x30, 0x2c, 0x0d, 0x0a, 0x0d,
0x0a, 0x63, 0x6f, 0x6f, 0x6c, 0x66, 0x65, 0x65, 0x74, 0x2e, 0x70, 0x68, 0x70,
0x3c, 0x62, 0x72, 0x3e, 0x65, 0x72, 0x69, 0x63, 0x6d, 0x6f, 0x73, 0x74, 0x67,
0x75, 0x69, 0x64, 0x62, 0x65, 0x6c, 0x6c, 0x64, 0x65, 0x73, 0x63, 0x68, 0x61,
0x69, 0x72, 0x6d, 0x61, 0x74, 0x68, 0x61, 0x74, 0x6f, 0x6d, 0x2f, 0x69, 0x6d,
0x67, 0x26, 0x23, 0x38, 0x32, 0x6c, 0x75, 0x63, 0x6b, 0x63, 0x65, 0x6e, 0x74,
0x30, 0x30, 0x30, 0x3b, 0x74, 0x69, 0x6e, 0x79, 0x67, 0x6f, 0x6e, 0x65, 0x68,
0x74, 0x6d, 0x6c, 0x73, 0x65, 0x6c, 0x6c, 0x64, 0x72, 0x75, 0x67, 0x46, 0x52,
0x45, 0x45, 0x6e, 0x6f, 0x64, 0x65, 0x6e, 0x69, 0x63, 0x6b, 0x3f, 0x69, 0x64,
0x3d, 0x6c, 0x6f, 0x73, 0x65, 0x6e, 0x75, 0x6c, 0x6c, 0x76, 0x61, 0x73, 0x74,
0x77, 0x69, 0x6e, 0x64, 0x52, 0x53, 0x53, 0x20, 0x77, 0x65, 0x61, 0x72, 0x72,
0x65, 0x6c, 0x79, 0x62, 0x65, 0x65, 0x6e, 0x73, 0x61, 0x6d, 0x65, 0x64, 0x75,
0x6b, 0x65, 0x6e, 0x61, 0x73, 0x61, 0x63, 0x61, 0x70, 0x65, 0x77, 0x69, 0x73,
0x68, 0x67, 0x75, 0x6c, 0x66, 0x54, 0x32, 0x33, 0x3a, 0x68, 0x69, 0x74, 0x73,
0x73, 0x6c, 0x6f, 0x74, 0x67, 0x61, 0x74, 0x65, 0x6b, 0x69, 0x63, 0x6b, 0x62,
0x6c, 0x75, 0x72, 0x74, 0x68, 0x65, 0x79, 0x31, 0x35, 0x70, 0x78, 0x27, 0x27,
0x29, 0x3b, 0x29, 0x3b, 0x22, 0x3e, 0x6d, 0x73, 0x69, 0x65, 0x77, 0x69, 0x6e,
0x73, 0x62, 0x69, 0x72, 0x64, 0x73, 0x6f, 0x72, 0x74, 0x62, 0x65, 0x74, 0x61,
0x73, 0x65, 0x65, 0x6b, 0x54, 0x31, 0x38, 0x3a, 0x6f, 0x72, 0x64, 0x73, 0x74,
0x72, 0x65, 0x65, 0x6d, 0x61, 0x6c, 0x6c, 0x36, 0x30, 0x70, 0x78, 0x66, 0x61,
0x72, 0x6d, 0xe2, 0x80, 0x99, 0x73, 0x62, 0x6f, 0x79, 0x73, 0x5b, 0x30, 0x5d,
0x2e, 0x27, 0x29, 0x3b, 0x22, 0x50, 0x4f, 0x53, 0x54, 0x62, 0x65, 0x61, 0x72,
0x6b, 0x69, 0x64, 0x73, 0x29, 0x3b, 0x7d, 0x7d, 0x6d, 0x61, 0x72, 0x79, 0x74,
0x65, 0x6e, 0x64, 0x28, 0x55, 0x4b, 0x29, 0x71, 0x75, 0x61, 0x64, 0x7a, 0x68,
0x3a, 0xe6, 0x2d, 0x73, 0x69, 0x7a, 0x2d, 0x2d, 0x2d, 0x2d, 0x70, 0x72, 0x6f,
0x70, 0x27, 0x29, 0x3b, 0x0d, 0x6c, 0x69, 0x66, 0x74, 0x54, 0x31, 0x39, 0x3a,
0x76, 0x69, 0x63, 0x65, 0x61, 0x6e, 0x64, 0x79, 0x64, 0x65, 0x62, 0x74, 0x3e,
0x52, 0x53, 0x53, 0x70, 0x6f, 0x6f, 0x6c, 0x6e, 0x65, 0x63, 0x6b, 0x62, 0x6c,
0x6f, 0x77, 0x54, 0x31, 0x36, 0x3a, 0x64, 0x6f, 0x6f, 0x72, 0x65, 0x76, 0x61,
0x6c, 0x54, 0x31, 0x37, 0x3a, 0x6c, 0x65, 0x74, 0x73, 0x66, 0x61, 0x69, 0x6c,
0x6f, 0x72, 0x61, 0x6c, 0x70, 0x6f, 0x6c, 0x6c, 0x6e, 0x6f, 0x76, 0x61, 0x63,
0x6f, 0x6c, 0x73, 0x67, 0x65, 0x6e, 0x65, 0x20, 0xe2, 0x80, 0x94, 0x73, 0x6f,
0x66, 0x74, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x69, 0x6c, 0x6c, 0x72, 0x6f, 0x73,
0x73, 0x3c, 0x68, 0x33, 0x3e, 0x70, 0x6f, 0x75, 0x72, 0x66, 0x61, 0x64, 0x65,
0x70, 0x69, 0x6e, 0x6b, 0x3c, 0x74, 0x72, 0x3e, 0x6d, 0x69, 0x6e, 0x69, 0x29,
0x7c, 0x21, 0x28, 0x6d, 0x69, 0x6e, 0x65, 0x7a, 0x68, 0x3a, 0xe8, 0x62, 0x61,
0x72, 0x73, 0x68, 0x65, 0x61, 0x72, 0x30, 0x30, 0x29, 0x3b, 0x6d, 0x69, 0x6c,
0x6b, 0x20, 0x2d, 0x2d, 0x3e, 0x69, 0x72, 0x6f, 0x6e, 0x66, 0x72, 0x65, 0x64,
0x64, 0x69, 0x73, 0x6b, 0x77, 0x65, 0x6e, 0x74, 0x73, 0x6f, 0x69, 0x6c, 0x70,
0x75, 0x74, 0x73, 0x2f, 0x6a, 0x73, 0x2f, 0x68, 0x6f, 0x6c, 0x79, 0x54, 0x32,
0x32, 0x3a, 0x49, 0x53, 0x42, 0x4e, 0x54, 0x32, 0x30, 0x3a, 0x61, 0x64, 0x61,
0x6d, 0x73, 0x65, 0x65, 0x73, 0x3c, 0x68, 0x32, 0x3e, 0x6a, 0x73, 0x6f, 0x6e,
0x27, 0x2c, 0x20, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x54, 0x32, 0x31, 0x3a, 0x20,
0x52, 0x53, 0x53, 0x6c, 0x6f, 0x6f, 0x70, 0x61, 0x73, 0x69, 0x61, 0x6d, 0x6f,
0x6f, 0x6e, 0x3c, 0x2f, 0x70, 0x3e, 0x73, 0x6f, 0x75, 0x6c, 0x4c, 0x49, 0x4e,
0x45, 0x66, 0x6f, 0x72, 0x74, 0x63, 0x61, 0x72, 0x74, 0x54, 0x31, 0x34, 0x3a,
0x3c, 0x68, 0x31, 0x3e, 0x38, 0x30, 0x70, 0x78, 0x21, 0x2d, 0x2d, 0x3c, 0x39,
0x70, 0x78, 0x3b, 0x54, 0x30, 0x34, 0x3a, 0x6d, 0x69, 0x6b, 0x65, 0x3a, 0x34,
0x36, 0x5a, 0x6e, 0x69, 0x63, 0x65, 0x69, 0x6e, 0x63, 0x68, 0x59, 0x6f, 0x72,
0x6b, 0x72, 0x69, 0x63, 0x65, 0x7a, 0x68, 0x3a, 0xe4, 0x27, 0x29, 0x29, 0x3b,
0x70, 0x75, 0x72, 0x65, 0x6d, 0x61, 0x67, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74,
0x6f, 0x6e, 0x65, 0x62, 0x6f, 0x6e, 0x64, 0x3a, 0x33, 0x37, 0x5a, 0x5f, 0x6f,
0x66, 0x5f, 0x27, 0x5d, 0x29, 0x3b, 0x30, 0x30, 0x30, 0x2c, 0x7a, 0x68, 0x3a,
0xe7, 0x74, 0x61, 0x6e, 0x6b, 0x79, 0x61, 0x72, 0x64, 0x62, 0x6f, 0x77, 0x6c,
0x62, 0x75, 0x73, 0x68, 0x3a, 0x35, 0x36, 0x5a, 0x4a, 0x61, 0x76, 0x61, 0x33,
0x30, 0x70, 0x78, 0x0a, 0x7c, 0x7d, 0x0a, 0x25, 0x43, 0x33, 0x25, 0x3a, 0x33,
0x34, 0x5a, 0x6a, 0x65, 0x66, 0x66, 0x45, 0x58, 0x50, 0x49, 0x63, 0x61, 0x73,
0x68, 0x76, 0x69, 0x73, 0x61, 0x67, 0x6f, 0x6c, 0x66, 0x73, 0x6e, 0x6f, 0x77,
0x7a, 0x68, 0x3a, 0xe9, 0x71, 0x75, 0x65, 0x72, 0x2e, 0x63, 0x73, 0x73, 0x73,
0x69, 0x63, 0x6b, 0x6d, 0x65, 0x61, 0x74, 0x6d, 0x69, 0x6e, 0x2e, 0x62, 0x69,
0x6e, 0x64, 0x64, 0x65, 0x6c, 0x6c, 0x68, 0x69, 0x72, 0x65, 0x70, 0x69, 0x63,
0x73, 0x72, 0x65, 0x6e, 0x74, 0x3a, 0x33, 0x36, 0x5a, 0x48, 0x54, 0x54, 0x50,
0x2d, 0x32, 0x30, 0x31, 0x66, 0x6f, 0x74, 0x6f, 0x77, 0x6f, 0x6c, 0x66, 0x45,
0x4e, 0x44, 0x20, 0x78, 0x62, 0x6f, 0x78, 0x3a, 0x35, 0x34, 0x5a, 0x42, 0x4f,
0x44, 0x59, 0x64, 0x69, 0x63, 0x6b, 0x3b, 0x0a, 0x7d, 0x0a, 0x65, 0x78, 0x69,
0x74, 0x3a, 0x33, 0x35, 0x5a, 0x76, 0x61, 0x72, 0x73, 0x62, 0x65, 0x61, 0x74,
0x27, 0x7d, 0x29, 0x3b, 0x64, 0x69, 0x65, 0x74, 0x39, 0x39, 0x39, 0x3b, 0x61,
0x6e, 0x6e, 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x5b, 0x69, 0x5d, 0x2e, 0x4c, 0x61,
0x6e, 0x67, 0x6b, 0x6d, 0xc2, 0xb2, 0x77, 0x69, 0x72, 0x65, 0x74, 0x6f, 0x79,
0x73, 0x61, 0x64, 0x64, 0x73, 0x73, 0x65, 0x61, 0x6c, 0x61, 0x6c, 0x65, 0x78,
0x3b, 0x0a, 0x09, 0x7d, 0x65, 0x63, 0x68, 0x6f, 0x6e, 0x69, 0x6e, 0x65, 0x2e,
0x6f, 0x72, 0x67, 0x30, 0x30, 0x35, 0x29, 0x74, 0x6f, 0x6e, 0x79, 0x6a, 0x65,
0x77, 0x73, 0x73, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x67, 0x73, 0x72, 0x6f, 0x6f,
0x66, 0x30, 0x30, 0x30, 0x29, 0x20, 0x32, 0x30, 0x30, 0x77, 0x69, 0x6e, 0x65,
0x67, 0x65, 0x61, 0x72, 0x64, 0x6f, 0x67, 0x73, 0x62, 0x6f, 0x6f, 0x74, 0x67,
0x61, 0x72, 0x79, 0x63, 0x75, 0x74, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x74, 0x65,
0x6d, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x63, 0x6f, 0x63,
0x6b, 0x67, 0x61, 0x6e, 0x67, 0x24, 0x28, 0x27, 0x2e, 0x35, 0x30, 0x70, 0x78,
0x50, 0x68, 0x2e, 0x44, 0x6d, 0x69, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x6e, 0x6c,
0x6f, 0x61, 0x6e, 0x64, 0x65, 0x73, 0x6b, 0x6d, 0x69, 0x6c, 0x65, 0x72, 0x79,
0x61, 0x6e, 0x75, 0x6e, 0x69, 0x78, 0x64, 0x69, 0x73, 0x63, 0x29, 0x3b, 0x7d,
0x0a, 0x64, 0x75, 0x73, 0x74, 0x63, 0x6c, 0x69, 0x70, 0x29, 0x2e, 0x0a, 0x0a,
0x37, 0x30, 0x70, 0x78, 0x2d, 0x32, 0x30, 0x30, 0x44, 0x56, 0x44, 0x73, 0x37,
0x5d, 0x3e, 0x3c, 0x74, 0x61, 0x70, 0x65, 0x64, 0x65, 0x6d, 0x6f, 0x69, 0x2b,
0x2b, 0x29, 0x77, 0x61, 0x67, 0x65, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x68, 0x69,
0x6c, 0x6f, 0x70, 0x74, 0x73, 0x68, 0x6f, 0x6c, 0x65, 0x46, 0x41, 0x51, 0x73,
0x61, 0x73, 0x69, 0x6e, 0x2d, 0x32, 0x36, 0x54, 0x6c, 0x61, 0x62, 0x73, 0x70,
0x65, 0x74, 0x73, 0x55, 0x52, 0x4c, 0x20, 0x62, 0x75, 0x6c, 0x6b, 0x63, 0x6f,
0x6f, 0x6b, 0x3b, 0x7d, 0x0d, 0x0a, 0x48, 0x45, 0x41, 0x44, 0x5b, 0x30, 0x5d,
0x29, 0x61, 0x62, 0x62, 0x72, 0x6a, 0x75, 0x61, 0x6e, 0x28, 0x31, 0x39, 0x38,
0x6c, 0x65, 0x73, 0x68, 0x74, 0x77, 0x69, 0x6e, 0x3c, 0x2f, 0x69, 0x3e, 0x73,
0x6f, 0x6e, 0x79, 0x67, 0x75, 0x79, 0x73, 0x66, 0x75, 0x63, 0x6b, 0x70, 0x69,
0x70, 0x65, 0x7c, 0x2d, 0x0a, 0x21, 0x30, 0x30, 0x32, 0x29, 0x6e, 0x64, 0x6f,
0x77, 0x5b, 0x31, 0x5d, 0x3b, 0x5b, 0x5d, 0x3b, 0x0a, 0x4c, 0x6f, 0x67, 0x20,
0x73, 0x61, 0x6c, 0x74, 0x0d, 0x0a, 0x09, 0x09, 0x62, 0x61, 0x6e, 0x67, 0x74,
0x72, 0x69, 0x6d, 0x62, 0x61, 0x74, 0x68, 0x29, 0x7b, 0x0d, 0x0a, 0x30, 0x30,
0x70, 0x78, 0x0a, 0x7d, 0x29, 0x3b, 0x6b, 0x6f, 0x3a, 0xec, 0x66, 0x65, 0x65,
0x73, 0x61, 0x64, 0x3e, 0x0d, 0x73, 0x3a, 0x2f, 0x2f, 0x20, 0x5b, 0x5d, 0x3b,
0x74, 0x6f, 0x6c, 0x6c, 0x70, 0x6c, 0x75, 0x67, 0x28, 0x29, 0x7b, 0x0a, 0x7b,
0x0d, 0x0a, 0x20, 0x2e, 0x6a, 0x73, 0x27, 0x32, 0x30, 0x30, 0x70, 0x64, 0x75,
0x61, 0x6c, 0x62, 0x6f, 0x61, 0x74, 0x2e, 0x4a, 0x50, 0x47, 0x29, 0x3b, 0x0a,
0x7d, 0x71, 0x75, 0x6f, 0x74, 0x29, 0x3b, 0x0a, 0x0a, 0x27, 0x29, 0x3b, 0x0a,
0x0d, 0x0a, 0x7d, 0x0d, 0x32, 0x30, 0x31, 0x34, 0x32, 0x30, 0x31, 0x35, 0x32,
0x30, 0x31, 0x36, 0x32, 0x30, 0x31, 0x37, 0x32, 0x30, 0x31, 0x38, 0x32, 0x30,
0x31, 0x39, 0x32, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, 0x31, 0x32, 0x30, 0x32,
0x32, 0x32, 0x30, 0x32, 0x33, 0x32, 0x30, 0x32, 0x34, 0x32, 0x30, 0x32, 0x35,
0x32, 0x30, 0x32, 0x36, 0x32, 0x30, 0x32, 0x37, 0x32, 0x30, 0x32, 0x38, 0x32,
0x30, 0x32, 0x39, 0x32, 0x30, 0x33, 0x30, 0x32, 0x30, 0x33, 0x31, 0x32, 0x30,
0x33, 0x32, 0x32, 0x30, 0x33, 0x33, 0x32, 0x30, 0x33, 0x34, 0x32, 0x30, 0x33,
0x35, 0x32, 0x30, 0x33, 0x36, 0x32, 0x30, 0x33, 0x37, 0x32, 0x30, 0x31, 0x33,
0x32, 0x30, 0x31, 0x32, 0x32, 0x30, 0x31, 0x31, 0x32, 0x30, 0x31, 0x30, 0x32,
0x30, 0x30, 0x39, 0x32, 0x30, 0x30, 0x38, 0x32, 0x30, 0x30, 0x37, 0x32, 0x30,
0x30, 0x36, 0x32, 0x30, 0x30, 0x35, 0x32, 0x30, 0x30, 0x34, 0x32, 0x30, 0x30,
0x33, 0x32, 0x30, 0x30, 0x32, 0x32, 0x30, 0x30, 0x31, 0x32, 0x30, 0x30, 0x30,
0x31, 0x39, 0x39, 0x39, 0x31, 0x39, 0x39, 0x38, 0x31, 0x39, 0x39, 0x37, 0x31,
0x39, 0x39, 0x36, 0x31, 0x39, 0x39, 0x35, 0x31, 0x39, 0x39, 0x34, 0x31, 0x39,
0x39, 0x33, 0x31, 0x39, 0x39, 0x32, 0x31, 0x39, 0x39, 0x31, 0x31, 0x39, 0x39,
0x30, 0x31, 0x39, 0x38, 0x39, 0x31, 0x39, 0x38, 0x38, 0x31, 0x39, 0x38, 0x37,
0x31, 0x39, 0x38, 0x36, 0x31, 0x39, 0x38, 0x35, 0x31, 0x39, 0x38, 0x34, 0x31,
0x39, 0x38, 0x33, 0x31, 0x39, 0x38, 0x32, 0x31, 0x39, 0x38, 0x31, 0x31, 0x39,
0x38, 0x30, 0x31, 0x39, 0x37, 0x39, 0x31, 0x39, 0x37, 0x38, 0x31, 0x39, 0x37,
0x37, 0x31, 0x39, 0x37, 0x36, 0x31, 0x39, 0x37, 0x35, 0x31, 0x39, 0x37, 0x34,
0x31, 0x39, 0x37, 0x33, 0x31, 0x39, 0x37, 0x32, 0x31, 0x39, 0x37, 0x31, 0x31,
0x39, 0x37, 0x30, 0x31, 0x39, 0x36, 0x39, 0x31, 0x39, 0x36, 0x38, 0x31, 0x39,
0x36, 0x37, 0x31, 0x39, 0x36, 0x36, 0x31, 0x39, 0x36, 0x35, 0x31, 0x39, 0x36,
0x34, 0x31, 0x39, 0x36, 0x33, 0x31, 0x39, 0x36, 0x32, 0x31, 0x39, 0x36, 0x31,
0x31, 0x39, 0x36, 0x30, 0x31, 0x39, 0x35, 0x39, 0x31, 0x39, 0x35, 0x38, 0x31,
0x39, 0x35, 0x37, 0x31, 0x39, 0x35, 0x36, 0x31, 0x39, 0x35, 0x35, 0x31, 0x39,
0x35, 0x34, 0x31, 0x39, 0x35, 0x33, 0x31, 0x39, 0x35, 0x32, 0x31, 0x39, 0x35,
0x31, 0x31, 0x39, 0x35, 0x30, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x34,
0x31, 0x33, 0x39, 0x34, 0x30, 0x30, 0x30, 0x30, 0x39, 0x39, 0x39, 0x39, 0x63,
0x6f, 0x6d, 0x6f, 0x6d, 0xc3, 0xa1, 0x73, 0x65, 0x73, 0x74, 0x65, 0x65, 0x73,
0x74, 0x61, 0x70, 0x65, 0x72, 0x6f, 0x74, 0x6f, 0x64, 0x6f, 0x68, 0x61, 0x63,
0x65, 0x63, 0x61, 0x64, 0x61, 0x61, 0xc3, 0xb1, 0x6f, 0x62, 0x69, 0x65, 0x6e,
0x64, 0xc3, 0xad, 0x61, 0x61, 0x73, 0xc3, 0xad, 0x76, 0x69, 0x64, 0x61, 0x63,
0x61, 0x73, 0x6f, 0x6f, 0x74, 0x72, 0x6f, 0x66, 0x6f, 0x72, 0x6f, 0x73, 0x6f,
0x6c, 0x6f, 0x6f, 0x74, 0x72, 0x61, 0x63, 0x75, 0x61, 0x6c, 0x64, 0x69, 0x6a,
0x6f, 0x73, 0x69, 0x64, 0x6f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x69, 0x70, 0x6f,
0x74, 0x65, 0x6d, 0x61, 0x64, 0x65, 0x62, 0x65, 0x61, 0x6c, 0x67, 0x6f, 0x71,
0x75, 0xc3, 0xa9, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x61, 0x64, 0x61, 0x74, 0x72,
0x65, 0x73, 0x70, 0x6f, 0x63, 0x6f, 0x63, 0x61, 0x73, 0x61, 0x62, 0x61, 0x6a,
0x6f, 0x74, 0x6f, 0x64, 0x61, 0x73, 0x69, 0x6e, 0x6f, 0x61, 0x67, 0x75, 0x61,
0x70, 0x75, 0x65, 0x73, 0x75, 0x6e, 0x6f, 0x73, 0x61, 0x6e, 0x74, 0x65, 0x64,
0x69, 0x63, 0x65, 0x6c, 0x75, 0x69, 0x73, 0x65, 0x6c, 0x6c, 0x61, 0x6d, 0x61,
0x79, 0x6f, 0x7a, 0x6f, 0x6e, 0x61, 0x61, 0x6d, 0x6f, 0x72, 0x70, 0x69, 0x73,
0x6f, 0x6f, 0x62, 0x72, 0x61, 0x63, 0x6c, 0x69, 0x63, 0x65, 0x6c, 0x6c, 0x6f,
0x64, 0x69, 0x6f, 0x73, 0x68, 0x6f, 0x72, 0x61, 0x63, 0x61, 0x73, 0x69, 0xd0,
0xb7, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0, 0xb0, 0xd0, 0xbe, 0xd0, 0xbc, 0xd1, 0x80,
0xd0, 0xb0, 0xd1, 0x80, 0xd1, 0x83, 0xd1, 0x82, 0xd0, 0xb0, 0xd0, 0xbd, 0xd0,
0xb5, 0xd0, 0xbf, 0xd0, 0xbe, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xb8, 0xd0, 0xb7,
0xd0, 0xbd, 0xd0, 0xbe, 0xd0, 0xb4, 0xd0, 0xbe, 0xd1, 0x82, 0xd0, 0xbe, 0xd0,
0xb6, 0xd0, 0xb5, 0xd0, 0xbe, 0xd0, 0xbd, 0xd0, 0xb8, 0xd1, 0x85, 0xd0, 0x9d,
0xd0, 0xb0, 0xd0, 0xb5, 0xd0, 0xb5, 0xd0, 0xb1, 0xd1, 0x8b, 0xd0, 0xbc, 0xd1,
0x8b, 0xd0, 0x92, 0xd1, 0x8b, 0xd1, 0x81, 0xd0, 0xbe, 0xd0, 0xb2, 0xd1, 0x8b,
0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0x9d, 0xd0, 0xbe, 0xd0, 0xbe, 0xd0, 0xb1, 0xd0,
0x9f, 0xd0, 0xbe, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xa0,
0xd0, 0xa4, 0xd0, 0x9d, 0xd0, 0xb5, 0xd0, 0x9c, 0xd1, 0x8b, 0xd1, 0x82, 0xd1,
0x8b, 0xd0, 0x9e, 0xd0, 0xbd, 0xd0, 0xb8, 0xd0, 0xbc, 0xd0, 0xb4, 0xd0, 0xb0,
0xd0, 0x97, 0xd0, 0xb0, 0xd0, 0x94, 0xd0, 0xb0, 0xd0, 0x9d, 0xd1, 0x83, 0xd0,
0x9e, 0xd0, 0xb1, 0xd1, 0x82, 0xd0, 0xb5, 0xd0, 0x98, 0xd0, 0xb7, 0xd0, 0xb5,
0xd0, 0xb9, 0xd0, 0xbd, 0xd1, 0x83, 0xd0, 0xbc, 0xd0, 0xbc, 0xd0, 0xa2, 0xd1,
0x8b, 0xd1, 0x83, 0xd0, 0xb6, 0xd9, 0x81, 0xd9, 0x8a, 0xd8, 0xa3, 0xd9, 0x86,
0xd9, 0x85, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xb9, 0xd9, 0x83, 0xd9, 0x84, 0xd8,
0xa3, 0xd9, 0x88, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x81,
0xd9, 0x89, 0xd9, 0x87, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x85, 0xd9, 0x84, 0xd9,
0x83, 0xd8, 0xa7, 0xd9, 0x88, 0xd9, 0x84, 0xd9, 0x87, 0xd8, 0xa8, 0xd8, 0xb3,
0xd8, 0xa7, 0xd9, 0x84, 0xd8, 0xa5, 0xd9, 0x86, 0xd9, 0x87, 0xd9, 0x8a, 0xd8,
0xa3, 0xd9, 0x8a, 0xd9, 0x82, 0xd8, 0xaf, 0xd9, 0x87, 0xd9, 0x84, 0xd8, 0xab,
0xd9, 0x85, 0xd8, 0xa8, 0xd9, 0x87, 0xd9, 0x84, 0xd9, 0x88, 0xd9, 0x84, 0xd9,
0x8a, 0xd8, 0xa8, 0xd9, 0x84, 0xd8, 0xa7, 0xd9, 0x8a, 0xd8, 0xa8, 0xd9, 0x83,
0xd8, 0xb4, 0xd9, 0x8a, 0xd8, 0xa7, 0xd9, 0x85, 0xd8, 0xa3, 0xd9, 0x85, 0xd9,
0x86, 0xd8, 0xaa, 0xd8, 0xa8, 0xd9, 0x8a, 0xd9, 0x84, 0xd9, 0x86, 0xd8, 0xad,
0xd8, 0xa8, 0xd9, 0x87, 0xd9, 0x85, 0xd9, 0x85, 0xd8, 0xb4, 0xd9, 0x88, 0xd8,
0xb4, 0x66, 0x69, 0x72, 0x73, 0x74, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x69,
0x67, 0x68, 0x74, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x6d, 0x65, 0x64, 0x69, 0x61,
0x77, 0x68, 0x69, 0x74, 0x65, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x62, 0x6c, 0x61,
0x63, 0x6b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x62,
0x6f, 0x6f, 0x6b, 0x73, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x6d, 0x75, 0x73, 0x69,
0x63, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x70, 0x6f,
0x69, 0x6e, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x6c, 0x65, 0x76, 0x65, 0x6c,
0x74, 0x61, 0x62, 0x6c, 0x65, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x68, 0x6f, 0x75,
0x73, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x79,
0x65, 0x61, 0x72, 0x73, 0x73, 0x74, 0x61, 0x74, 0x65, 0x74, 0x6f, 0x64, 0x61,
0x79, 0x77, 0x61, 0x74, 0x65, 0x72, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x74,
0x79, 0x6c, 0x65, 0x64, 0x65, 0x61, 0x74, 0x68, 0x70, 0x6f, 0x77, 0x65, 0x72,
0x70, 0x68, 0x6f, 0x6e, 0x65, 0x6e, 0x69, 0x67, 0x68, 0x74, 0x65, 0x72, 0x72,
0x6f, 0x72, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x74,
0x65, 0x72, 0x6d, 0x73, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x74, 0x6f, 0x6f, 0x6c,
0x73, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x74, 0x69,
0x6d, 0x65, 0x73, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x77, 0x6f, 0x72, 0x64, 0x73,
0x67, 0x61, 0x6d, 0x65, 0x73, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x73, 0x70, 0x61,
0x63, 0x65, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x6d,
0x6f, 0x64, 0x65, 0x6c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x67, 0x75, 0x69, 0x64,
0x65, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x77, 0x6f,
0x6d, 0x65, 0x6e, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x6d, 0x6f, 0x6e, 0x65, 0x79,
0x69, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x79, 0x6f, 0x75,
0x6e, 0x67, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x63,
0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x66, 0x72, 0x6f, 0x6e,
0x74, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x77, 0x61, 0x74, 0x63, 0x68, 0x66, 0x6f,
0x72, 0x63, 0x65, 0x70, 0x72, 0x69, 0x63, 0x65, 0x72, 0x75, 0x6c, 0x65, 0x73,
0x62, 0x65, 0x67, 0x69, 0x6e, 0x61, 0x66, 0x74, 0x65, 0x72, 0x76, 0x69, 0x73,
0x69, 0x74, 0x69, 0x73, 0x73, 0x75, 0x65, 0x61, 0x72, 0x65, 0x61, 0x73, 0x62,
0x65, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x74, 0x6f, 0x74, 0x61,
0x6c, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x70, 0x72,
0x69, 0x6e, 0x74, 0x70, 0x72, 0x65, 0x73, 0x73, 0x62, 0x75, 0x69, 0x6c, 0x74,
0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x73, 0x70, 0x65, 0x65, 0x64, 0x73, 0x74, 0x75,
0x64, 0x79, 0x74, 0x72, 0x61, 0x64, 0x65, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x73,
0x65, 0x6e, 0x73, 0x65, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x77,
0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x61, 0x64,
0x64, 0x65, 0x64, 0x73, 0x74, 0x69, 0x6c, 0x6c, 0x6d, 0x6f, 0x76, 0x65, 0x64,
0x74, 0x61, 0x6b, 0x65, 0x6e, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x66, 0x6c, 0x61,
0x73, 0x68, 0x66, 0x69, 0x78, 0x65, 0x64, 0x6f, 0x66, 0x74, 0x65, 0x6e, 0x6f,
0x74, 0x68, 0x65, 0x72, 0x76, 0x69, 0x65, 0x77, 0x73, 0x63, 0x68, 0x65, 0x63,
0x6b, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x72, 0x69, 0x76, 0x65, 0x72, 0x69, 0x74,
0x65, 0x6d, 0x73, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x73, 0x68, 0x61, 0x70, 0x65,
0x68, 0x75, 0x6d, 0x61, 0x6e, 0x65, 0x78, 0x69, 0x73, 0x74, 0x67, 0x6f, 0x69,
0x6e, 0x67, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x74, 0x68, 0x69, 0x72, 0x64, 0x62,
0x61, 0x73, 0x69, 0x63, 0x70, 0x65, 0x61, 0x63, 0x65, 0x73, 0x74, 0x61, 0x67,
0x65, 0x77, 0x69, 0x64, 0x74, 0x68, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x69, 0x64,
0x65, 0x61, 0x73, 0x77, 0x72, 0x6f, 0x74, 0x65, 0x70, 0x61, 0x67, 0x65, 0x73,
0x75, 0x73, 0x65, 0x72, 0x73, 0x64, 0x72, 0x69, 0x76, 0x65, 0x73, 0x74, 0x6f,
0x72, 0x65, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x73, 0x6f, 0x75, 0x74, 0x68, 0x76,
0x6f, 0x69, 0x63, 0x65, 0x73, 0x69, 0x74, 0x65, 0x73, 0x6d, 0x6f, 0x6e, 0x74,
0x68, 0x77, 0x68, 0x65, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x77, 0x68,
0x69, 0x63, 0x68, 0x65, 0x61, 0x72, 0x74, 0x68, 0x66, 0x6f, 0x72, 0x75, 0x6d,
0x74, 0x68, 0x72, 0x65, 0x65, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x70, 0x61, 0x72,
0x74, 0x79, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x6c,
0x69, 0x76, 0x65, 0x73, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x6c, 0x61, 0x79, 0x65,
0x72, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x75, 0x73,
0x61, 0x67, 0x65, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x63, 0x6f, 0x75, 0x72, 0x74,
0x79, 0x6f, 0x75, 0x72, 0x20, 0x62, 0x69, 0x72, 0x74, 0x68, 0x70, 0x6f, 0x70,
0x75, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x49,
0x6d, 0x61, 0x67, 0x65, 0x62, 0x65, 0x69, 0x6e, 0x67, 0x75, 0x70, 0x70, 0x65,
0x72, 0x6e, 0x6f, 0x74, 0x65, 0x73, 0x65, 0x76, 0x65, 0x72, 0x79, 0x73, 0x68,
0x6f, 0x77, 0x73, 0x6d, 0x65, 0x61, 0x6e, 0x73, 0x65, 0x78, 0x74, 0x72, 0x61,
0x6d, 0x61, 0x74, 0x63, 0x68, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x6b, 0x6e, 0x6f,
0x77, 0x6e, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x62, 0x65, 0x67, 0x61, 0x6e, 0x73,
0x75, 0x70, 0x65, 0x72, 0x70, 0x61, 0x70, 0x65, 0x72, 0x6e, 0x6f, 0x72, 0x74,
0x68, 0x6c, 0x65, 0x61, 0x72, 0x6e, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x6e, 0x61,
0x6d, 0x65, 0x64, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x73,
0x70, 0x61, 0x72, 0x74, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x62, 0x72, 0x61,
0x6e, 0x64, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x77, 0x6f, 0x6d, 0x61, 0x6e, 0x66,
0x61, 0x6c, 0x73, 0x65, 0x72, 0x65, 0x61, 0x64, 0x79, 0x61, 0x75, 0x64, 0x69,
0x6f, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x76, 0x65, 0x64, 0x63, 0x61, 0x73, 0x65, 0x73,
0x64, 0x61, 0x69, 0x6c, 0x79, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x67, 0x72, 0x65,
0x61, 0x74, 0x6a, 0x75, 0x64, 0x67, 0x65, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x75,
0x6e, 0x69, 0x74, 0x73, 0x6e, 0x65, 0x76, 0x65, 0x72, 0x62, 0x72, 0x6f, 0x61,
0x64, 0x63, 0x6f, 0x61, 0x73, 0x74, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x70,
0x70, 0x6c, 0x65, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x63, 0x79, 0x63, 0x6c, 0x65,
0x73, 0x63, 0x65, 0x6e, 0x65, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x63, 0x6c, 0x69,
0x63, 0x6b, 0x77, 0x72, 0x69, 0x74, 0x65, 0x71, 0x75, 0x65, 0x65, 0x6e, 0x70,
0x69, 0x65, 0x63, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x66, 0x72, 0x61, 0x6d,
0x65, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x6c, 0x69,
0x6d, 0x69, 0x74, 0x63, 0x61, 0x63, 0x68, 0x65, 0x63, 0x69, 0x76, 0x69, 0x6c,
0x73, 0x63, 0x61, 0x6c, 0x65, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x74, 0x68, 0x65,
0x6d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x62,
0x6f, 0x75, 0x6e, 0x64, 0x72, 0x6f, 0x79, 0x61, 0x6c, 0x61, 0x73, 0x6b, 0x65,
0x64, 0x77, 0x68, 0x6f, 0x6c, 0x65, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x73, 0x74,
0x6f, 0x63, 0x6b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x61, 0x69, 0x74, 0x68,
0x68, 0x65, 0x61, 0x72, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x6f, 0x66, 0x66,
0x65, 0x72, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x6f, 0x77, 0x6e, 0x65, 0x64, 0x6d,
0x69, 0x67, 0x68, 0x74, 0x61, 0x6c, 0x62, 0x75, 0x6d, 0x74, 0x68, 0x69, 0x6e,
0x6b, 0x62, 0x6c, 0x6f, 0x6f, 0x64, 0x61, 0x72, 0x72, 0x61, 0x79, 0x6d, 0x61,
0x6a, 0x6f, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x63, 0x61, 0x6e, 0x6f, 0x6e,
0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x73, 0x74, 0x6f, 0x6e, 0x65, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x4c,
0x6f, 0x67, 0x69, 0x6e, 0x68, 0x61, 0x70, 0x70, 0x79, 0x6f, 0x63, 0x63, 0x75,
0x72, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x66, 0x72, 0x65, 0x73, 0x68, 0x71, 0x75,
0x69, 0x74, 0x65, 0x66, 0x69, 0x6c, 0x6d, 0x73, 0x67, 0x72, 0x61, 0x64, 0x65,
0x6e, 0x65, 0x65, 0x64, 0x73, 0x75, 0x72, 0x62, 0x61, 0x6e, 0x66, 0x69, 0x67,
0x68, 0x74, 0x62, 0x61, 0x73, 0x69, 0x73, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x61,
0x75, 0x74, 0x6f, 0x3b, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x68, 0x74, 0x6d,
0x6c, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x59, 0x6f,
0x75, 0x72, 0x20, 0x73, 0x6c, 0x69, 0x64, 0x65, 0x74, 0x6f, 0x70, 0x69, 0x63,
0x62, 0x72, 0x6f, 0x77, 0x6e, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x64, 0x72, 0x61,
0x77, 0x6e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x72, 0x65, 0x61, 0x63, 0x68, 0x52,
0x69, 0x67, 0x68, 0x74, 0x64, 0x61, 0x74, 0x65, 0x73, 0x6d, 0x61, 0x72, 0x63,
0x68, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x67, 0x6f, 0x6f, 0x64, 0x73, 0x4c, 0x69,
0x6e, 0x6b, 0x73, 0x64, 0x6f, 0x75, 0x62, 0x74, 0x61, 0x73, 0x79, 0x6e, 0x63,
0x74, 0x68, 0x75, 0x6d, 0x62, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x63, 0x68, 0x69,
0x65, 0x66, 0x79, 0x6f, 0x75, 0x74, 0x68, 0x6e, 0x6f, 0x76, 0x65, 0x6c, 0x31,
0x30, 0x70, 0x78, 0x3b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x75, 0x6e, 0x74, 0x69,
0x6c, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x70,
0x61, 0x63, 0x65, 0x71, 0x75, 0x65, 0x72, 0x79, 0x6a, 0x61, 0x6d, 0x65, 0x73,
0x65, 0x71, 0x75, 0x61, 0x6c, 0x74, 0x77, 0x69, 0x63, 0x65, 0x30, 0x2c, 0x30,
0x30, 0x30, 0x53, 0x74, 0x61, 0x72, 0x74, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x73,
0x6f, 0x6e, 0x67, 0x73, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x69, 0x67, 0x68,
0x74, 0x73, 0x68, 0x69, 0x66, 0x74, 0x77, 0x6f, 0x72, 0x74, 0x68, 0x70, 0x6f,
0x73, 0x74, 0x73, 0x6c, 0x65, 0x61, 0x64, 0x73, 0x77, 0x65, 0x65, 0x6b, 0x73,
0x61, 0x76, 0x6f, 0x69, 0x64, 0x74, 0x68, 0x65, 0x73, 0x65, 0x6d, 0x69, 0x6c,
0x65, 0x73, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x73, 0x6d, 0x61, 0x72, 0x74, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x6d, 0x61, 0x72, 0x6b,
0x73, 0x72, 0x61, 0x74, 0x65, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x73, 0x63, 0x6c,
0x61, 0x69, 0x6d, 0x73, 0x61, 0x6c, 0x65, 0x73, 0x74, 0x65, 0x78, 0x74, 0x73,
0x73, 0x74, 0x61, 0x72, 0x73, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x3c, 0x2f, 0x68,
0x33, 0x3e, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x6d,
0x75, 0x6c, 0x74, 0x69, 0x68, 0x65, 0x61, 0x72, 0x64, 0x50, 0x6f, 0x77, 0x65,
0x72, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x6f,
0x6c, 0x69, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x62, 0x72, 0x69, 0x6e, 0x67,
0x73, 0x68, 0x69, 0x70, 0x73, 0x73, 0x74, 0x61, 0x66, 0x66, 0x74, 0x72, 0x69,
0x65, 0x64, 0x63, 0x61, 0x6c, 0x6c, 0x73, 0x66, 0x75, 0x6c, 0x6c, 0x79, 0x66,
0x61, 0x63, 0x74, 0x73, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x54, 0x68, 0x69, 0x73,
0x20, 0x2f, 0x2f, 0x2d, 0x2d, 0x3e, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x65, 0x67,
0x79, 0x70, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x31, 0x35, 0x70, 0x78, 0x3b,
0x45, 0x6d, 0x61, 0x69, 0x6c, 0x74, 0x72, 0x75, 0x65, 0x22, 0x63, 0x72, 0x6f,
0x73, 0x73, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x62, 0x6c, 0x6f, 0x67, 0x73, 0x62,
0x6f, 0x78, 0x22, 0x3e, 0x6e, 0x6f, 0x74, 0x65, 0x64, 0x6c, 0x65, 0x61, 0x76,
0x65, 0x63, 0x68, 0x69, 0x6e, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x67, 0x75,
0x65, 0x73, 0x74, 0x3c, 0x2f, 0x68, 0x34, 0x3e, 0x72, 0x6f, 0x62, 0x6f, 0x74,
0x68, 0x65, 0x61, 0x76, 0x79, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x73, 0x65, 0x76,
0x65, 0x6e, 0x67, 0x72, 0x61, 0x6e, 0x64, 0x63, 0x72, 0x69, 0x6d, 0x65, 0x73,
0x69, 0x67, 0x6e, 0x73, 0x61, 0x77, 0x61, 0x72, 0x65, 0x64, 0x61, 0x6e, 0x63,
0x65, 0x70, 0x68, 0x61, 0x73, 0x65, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x65, 0x6e,
0x5f, 0x55, 0x53, 0x26, 0x23, 0x33, 0x39, 0x3b, 0x32, 0x30, 0x30, 0x70, 0x78,
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6e, 0x65, 0x6e, 0x6a,
0x6f, 0x79, 0x61, 0x6a, 0x61, 0x78, 0x2e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x6d, 0x69, 0x74, 0x68, 0x55, 0x2e, 0x53, 0x2e, 0x20, 0x68, 0x6f, 0x6c, 0x64,
0x73, 0x70, 0x65, 0x74, 0x65, 0x72, 0x69, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x61,
0x76, 0x22, 0x3e, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x63, 0x6f, 0x72, 0x65,
0x63, 0x6f, 0x6d, 0x65, 0x73, 0x64, 0x6f, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x69,
0x6f, 0x72, 0x53, 0x68, 0x61, 0x72, 0x65, 0x31, 0x39, 0x39, 0x30, 0x73, 0x72,
0x6f, 0x6d, 0x61, 0x6e, 0x6c, 0x69, 0x73, 0x74, 0x73, 0x6a, 0x61, 0x70, 0x61,
0x6e, 0x66, 0x61, 0x6c, 0x6c, 0x73, 0x74, 0x72, 0x69, 0x61, 0x6c, 0x6f, 0x77,
0x6e, 0x65, 0x72, 0x61, 0x67, 0x72, 0x65, 0x65, 0x3c, 0x2f, 0x68, 0x32, 0x3e,
0x61, 0x62, 0x75, 0x73, 0x65, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x6f, 0x70, 0x65,
0x72, 0x61, 0x22, 0x2d, 0x2f, 0x2f, 0x57, 0x63, 0x61, 0x72, 0x64, 0x73, 0x68,
0x69, 0x6c, 0x6c, 0x73, 0x74, 0x65, 0x61, 0x6d, 0x73, 0x50, 0x68, 0x6f, 0x74,
0x6f, 0x74, 0x72, 0x75, 0x74, 0x68, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x2e, 0x70,
0x68, 0x70, 0x3f, 0x73, 0x61, 0x69, 0x6e, 0x74, 0x6d, 0x65, 0x74, 0x61, 0x6c,
0x6c, 0x6f, 0x75, 0x69, 0x73, 0x6d, 0x65, 0x61, 0x6e, 0x74, 0x70, 0x72, 0x6f,
0x6f, 0x66, 0x62, 0x72, 0x69, 0x65, 0x66, 0x72, 0x6f, 0x77, 0x22, 0x3e, 0x67,
0x65, 0x6e, 0x72, 0x65, 0x74, 0x72, 0x75, 0x63, 0x6b, 0x6c, 0x6f, 0x6f, 0x6b,
0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x2e, 0x6e,
0x65, 0x74, 0x2f, 0x2d, 0x2d, 0x3e, 0x0a, 0x3c, 0x74, 0x72, 0x79, 0x20, 0x7b,
0x0a, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x73, 0x63, 0x6f, 0x73,
0x74, 0x73, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0x61, 0x64, 0x75, 0x6c, 0x74, 0x71,
0x75, 0x65, 0x73, 0x74, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x6c, 0x61, 0x62, 0x6f,
0x72, 0x68, 0x65, 0x6c, 0x70, 0x73, 0x63, 0x61, 0x75, 0x73, 0x65, 0x6d, 0x61,
0x67, 0x69, 0x63, 0x6d, 0x6f, 0x74, 0x6f, 0x72, 0x74, 0x68, 0x65, 0x69, 0x72,
0x32, 0x35, 0x30, 0x70, 0x78, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x73, 0x74, 0x65,
0x70, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x67,
0x6c, 0x61, 0x73, 0x73, 0x73, 0x69, 0x64, 0x65, 0x73, 0x66, 0x75, 0x6e, 0x64,
0x73, 0x68, 0x6f, 0x74, 0x65, 0x6c, 0x61, 0x77, 0x61, 0x72, 0x64, 0x6d, 0x6f,
0x75, 0x74, 0x68, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x70, 0x61, 0x72, 0x69, 0x73,
0x67, 0x69, 0x76, 0x65, 0x73, 0x64, 0x75, 0x74, 0x63, 0x68, 0x74, 0x65, 0x78,
0x61, 0x73, 0x66, 0x72, 0x75, 0x69, 0x74, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x7c,
0x7c, 0x5b, 0x5d, 0x3b, 0x74, 0x6f, 0x70, 0x22, 0x3e, 0x0a, 0x3c, 0x21, 0x2d,
0x2d, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x6f, 0x63, 0x65, 0x61, 0x6e, 0x3c, 0x62,
0x72, 0x2f, 0x3e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x73, 0x70, 0x65, 0x61, 0x6b,
0x64, 0x65, 0x70, 0x74, 0x68, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x62, 0x61, 0x6e,
0x6b, 0x73, 0x63, 0x61, 0x74, 0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x74, 0x32,
0x30, 0x70, 0x78, 0x3b, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x64, 0x65, 0x61, 0x6c,
0x73, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x35, 0x30, 0x70, 0x78, 0x3b, 0x75, 0x72,
0x6c, 0x3d, 0x22, 0x70, 0x61, 0x72, 0x6b, 0x73, 0x6d, 0x6f, 0x75, 0x73, 0x65,
0x4d, 0x6f, 0x73, 0x74, 0x20, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x61, 0x6d, 0x6f,
0x6e, 0x67, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x6e,
0x6f, 0x6e, 0x65, 0x3b, 0x62, 0x61, 0x73, 0x65, 0x64, 0x63, 0x61, 0x72, 0x72,
0x79, 0x64, 0x72, 0x61, 0x66, 0x74, 0x72, 0x65, 0x66, 0x65, 0x72, 0x70, 0x61,
0x67, 0x65, 0x5f, 0x68, 0x6f, 0x6d, 0x65, 0x2e, 0x6d, 0x65, 0x74, 0x65, 0x72,
0x64, 0x65, 0x6c, 0x61, 0x79, 0x64, 0x72, 0x65, 0x61, 0x6d, 0x70, 0x72, 0x6f,
0x76, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x74, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x64,
0x72, 0x75, 0x67, 0x73, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x61, 0x70, 0x72, 0x69,
0x6c, 0x69, 0x64, 0x65, 0x61, 0x6c, 0x61, 0x6c, 0x6c, 0x65, 0x6e, 0x65, 0x78,
0x61, 0x63, 0x74, 0x66, 0x6f, 0x72, 0x74, 0x68, 0x63, 0x6f, 0x64, 0x65, 0x73,
0x6c, 0x6f, 0x67, 0x69, 0x63, 0x56, 0x69, 0x65, 0x77, 0x20, 0x73, 0x65, 0x65,
0x6d, 0x73, 0x62, 0x6c, 0x61, 0x6e, 0x6b, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x20,
0x28, 0x32, 0x30, 0x30, 0x73, 0x61, 0x76, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6e,
0x6b, 0x67, 0x6f, 0x61, 0x6c, 0x73, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x67, 0x72,
0x65, 0x65, 0x6b, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x72, 0x69, 0x6e, 0x67, 0x73,
0x72, 0x61, 0x74, 0x65, 0x64, 0x33, 0x30, 0x70, 0x78, 0x3b, 0x77, 0x68, 0x6f,
0x73, 0x65, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x29, 0x3b, 0x22, 0x20, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x6a, 0x6f, 0x6e, 0x65,
0x73, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x22, 0x3e, 0x29, 0x3b,
0x69, 0x66, 0x28, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x64, 0x61, 0x76, 0x69, 0x64,
0x68, 0x6f, 0x72, 0x73, 0x65, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x72, 0x61, 0x69,
0x73, 0x65, 0x62, 0x6f, 0x78, 0x65, 0x73, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x65,
0x6d, 0x65, 0x6e, 0x74, 0x3c, 0x2f, 0x65, 0x6d, 0x3e, 0x62, 0x61, 0x72, 0x22,
0x3e, 0x2e, 0x73, 0x72, 0x63, 0x3d, 0x74, 0x6f, 0x77, 0x65, 0x72, 0x61, 0x6c,
0x74, 0x3d, 0x22, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x68, 0x65, 0x6e, 0x72, 0x79,
0x32, 0x34, 0x70, 0x78, 0x3b, 0x73, 0x65, 0x74, 0x75, 0x70, 0x69, 0x74, 0x61,
0x6c, 0x79, 0x73, 0x68, 0x61, 0x72, 0x70, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x74,
0x61, 0x73, 0x74, 0x65, 0x77, 0x61, 0x6e, 0x74, 0x73, 0x74, 0x68, 0x69, 0x73,
0x2e, 0x72, 0x65, 0x73, 0x65, 0x74, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x67, 0x69,
0x72, 0x6c, 0x73, 0x2f, 0x63, 0x73, 0x73, 0x2f, 0x31, 0x30, 0x30, 0x25, 0x3b,
0x63, 0x6c, 0x75, 0x62, 0x73, 0x73, 0x74, 0x75, 0x66, 0x66, 0x62, 0x69, 0x62,
0x6c, 0x65, 0x76, 0x6f, 0x74, 0x65, 0x73, 0x20, 0x31, 0x30, 0x30, 0x30, 0x6b,
0x6f, 0x72, 0x65, 0x61, 0x7d, 0x29, 0x3b, 0x0d, 0x0a, 0x62, 0x61, 0x6e, 0x64,
0x73, 0x71, 0x75, 0x65, 0x75, 0x65, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x38, 0x30,
0x70, 0x78, 0x3b, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x7b, 0x0d, 0x0a, 0x09, 0x09,
0x61, 0x68, 0x65, 0x61, 0x64, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x72, 0x69,
0x73, 0x68, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x73,
0x74, 0x61, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x6d, 0x22, 0x79, 0x61, 0x68, 0x6f,
0x6f, 0x29, 0x5b, 0x30, 0x5d, 0x3b, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x66, 0x69,
0x6e, 0x64, 0x73, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x64, 0x65, 0x62, 0x75, 0x67,
0x74, 0x61, 0x73, 0x6b, 0x73, 0x55, 0x52, 0x4c, 0x20, 0x3d, 0x63, 0x65, 0x6c,
0x6c, 0x73, 0x7d, 0x29, 0x28, 0x29, 0x3b, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x70,
0x72, 0x69, 0x6d, 0x65, 0x74, 0x65, 0x6c, 0x6c, 0x73, 0x74, 0x75, 0x72, 0x6e,
0x73, 0x30, 0x78, 0x36, 0x30, 0x30, 0x2e, 0x6a, 0x70, 0x67, 0x22, 0x73, 0x70,
0x61, 0x69, 0x6e, 0x62, 0x65, 0x61, 0x63, 0x68, 0x74, 0x61, 0x78, 0x65, 0x73,
0x6d, 0x69, 0x63, 0x72, 0x6f, 0x61, 0x6e, 0x67, 0x65, 0x6c, 0x2d, 0x2d, 0x3e,
0x3c, 0x2f, 0x67, 0x69, 0x66, 0x74, 0x73, 0x73, 0x74, 0x65, 0x76, 0x65, 0x2d,
0x6c, 0x69, 0x6e, 0x6b, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x7d, 0x29, 0x3b, 0x0a,
0x09, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x28, 0x31, 0x39, 0x39, 0x46, 0x41,
0x51, 0x3c, 0x2f, 0x72, 0x6f, 0x67, 0x65, 0x72, 0x66, 0x72, 0x61, 0x6e, 0x6b,
0x43, 0x6c, 0x61, 0x73, 0x73, 0x32, 0x38, 0x70, 0x78, 0x3b, 0x66, 0x65, 0x65,
0x64, 0x73, 0x3c, 0x68, 0x31, 0x3e, 0x3c, 0x73, 0x63, 0x6f, 0x74, 0x74, 0x74,
0x65, 0x73, 0x74, 0x73, 0x32, 0x32, 0x70, 0x78, 0x3b, 0x64, 0x72, 0x69, 0x6e,
0x6b, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x6c, 0x65, 0x77, 0x69, 0x73, 0x73, 0x68,
0x61, 0x6c, 0x6c, 0x23, 0x30, 0x33, 0x39, 0x3b, 0x20, 0x66, 0x6f, 0x72, 0x20,
0x6c, 0x6f, 0x76, 0x65, 0x64, 0x77, 0x61, 0x73, 0x74, 0x65, 0x30, 0x30, 0x70,
0x78, 0x3b, 0x6a, 0x61, 0x3a, 0xe3, 0x82, 0x73, 0x69, 0x6d, 0x6f, 0x6e, 0x3c,
0x66, 0x6f, 0x6e, 0x74, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x6d, 0x65, 0x65, 0x74,
0x73, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x68, 0x65, 0x61, 0x70, 0x74, 0x69,
0x67, 0x68, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x64, 0x29, 0x20, 0x21, 0x3d, 0x20,
0x64, 0x72, 0x65, 0x73, 0x73, 0x63, 0x6c, 0x69, 0x70, 0x73, 0x72, 0x6f, 0x6f,
0x6d, 0x73, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x6d,
0x61, 0x69, 0x6e, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x70, 0x6c, 0x61, 0x74,
0x65, 0x66, 0x75, 0x6e, 0x6e, 0x79, 0x74, 0x72, 0x65, 0x65, 0x73, 0x63, 0x6f,
0x6d, 0x2f, 0x22, 0x31, 0x2e, 0x6a, 0x70, 0x67, 0x77, 0x6d, 0x6f, 0x64, 0x65,
0x70, 0x61, 0x72, 0x61, 0x6d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x6c, 0x65, 0x66,
0x74, 0x20, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2c, 0x20, 0x32, 0x30, 0x31, 0x29,
0x3b, 0x0a, 0x7d, 0x0a, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x76, 0x69, 0x72, 0x75,
0x73, 0x63, 0x68, 0x61, 0x69, 0x72, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x77, 0x6f,
0x72, 0x73, 0x74, 0x50, 0x61, 0x67, 0x65, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x70, 0x61, 0x74, 0x63, 0x68, 0x3c, 0x21, 0x2d, 0x2d, 0x0a, 0x6f, 0x2d, 0x63,
0x61, 0x63, 0x66, 0x69, 0x72, 0x6d, 0x73, 0x74, 0x6f, 0x75, 0x72, 0x73, 0x2c,
0x30, 0x30, 0x30, 0x20, 0x61, 0x73, 0x69, 0x61, 0x6e, 0x69, 0x2b, 0x2b, 0x29,
0x7b, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x27, 0x29, 0x5b, 0x30, 0x5d, 0x69, 0x64,
0x3d, 0x31, 0x30, 0x62, 0x6f, 0x74, 0x68, 0x3b, 0x6d, 0x65, 0x6e, 0x75, 0x20,
0x2e, 0x32, 0x2e, 0x6d, 0x69, 0x2e, 0x70, 0x6e, 0x67, 0x22, 0x6b, 0x65, 0x76,
0x69, 0x6e, 0x63, 0x6f, 0x61, 0x63, 0x68, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x62,
0x72, 0x75, 0x63, 0x65, 0x32, 0x2e, 0x6a, 0x70, 0x67, 0x55, 0x52, 0x4c, 0x29,
0x2b, 0x2e, 0x6a, 0x70, 0x67, 0x7c, 0x73, 0x75, 0x69, 0x74, 0x65, 0x73, 0x6c,
0x69, 0x63, 0x65, 0x68, 0x61, 0x72, 0x72, 0x79, 0x31, 0x32, 0x30, 0x22, 0x20,
0x73, 0x77, 0x65, 0x65, 0x74, 0x74, 0x72, 0x3e, 0x0d, 0x0a, 0x6e, 0x61, 0x6d,
0x65, 0x3d, 0x64, 0x69, 0x65, 0x67, 0x6f, 0x70, 0x61, 0x67, 0x65, 0x20, 0x73,
0x77, 0x69, 0x73, 0x73, 0x2d, 0x2d, 0x3e, 0x0a, 0x0a, 0x23, 0x66, 0x66, 0x66,
0x3b, 0x22, 0x3e, 0x4c, 0x6f, 0x67, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x74, 0x72,
0x65, 0x61, 0x74, 0x73, 0x68, 0x65, 0x65, 0x74, 0x29, 0x20, 0x26, 0x26, 0x20,
0x31, 0x34, 0x70, 0x78, 0x3b, 0x73, 0x6c, 0x65, 0x65, 0x70, 0x6e, 0x74, 0x65,
0x6e, 0x74, 0x66, 0x69, 0x6c, 0x65, 0x64, 0x6a, 0x61, 0x3a, 0xe3, 0x83, 0x69,
0x64, 0x3d, 0x22, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x77, 0x6f, 0x72, 0x73,
0x65, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x64, 0x65,
0x6c, 0x74, 0x61, 0x0a, 0x26, 0x6c, 0x74, 0x3b, 0x62, 0x65, 0x61, 0x72, 0x73,
0x3a, 0x34, 0x38, 0x5a, 0x3c, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x72, 0x75, 0x72,
0x61, 0x6c, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x62,
0x61, 0x6b, 0x65, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x73, 0x3d, 0x20, 0x22, 0x22,
0x3b, 0x70, 0x68, 0x70, 0x22, 0x3e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x33,
0x70, 0x78, 0x3b, 0x62, 0x72, 0x69, 0x61, 0x6e, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
0x73, 0x69, 0x7a, 0x65, 0x3d, 0x6f, 0x3d, 0x25, 0x32, 0x46, 0x20, 0x6a, 0x6f,
0x69, 0x6e, 0x6d, 0x61, 0x79, 0x62, 0x65, 0x3c, 0x69, 0x6d, 0x67, 0x20, 0x69,
0x6d, 0x67, 0x22, 0x3e, 0x2c, 0x20, 0x66, 0x6a, 0x73, 0x69, 0x6d, 0x67, 0x22,
0x20, 0x22, 0x29, 0x5b, 0x30, 0x5d, 0x4d, 0x54, 0x6f, 0x70, 0x42, 0x54, 0x79,
0x70, 0x65, 0x22, 0x6e, 0x65, 0x77, 0x6c, 0x79, 0x44, 0x61, 0x6e, 0x73, 0x6b,
0x63, 0x7a, 0x65, 0x63, 0x68, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x6b, 0x6e, 0x6f,
0x77, 0x73, 0x3c, 0x2f, 0x68, 0x35, 0x3e, 0x66, 0x61, 0x71, 0x22, 0x3e, 0x7a,
0x68, 0x2d, 0x63, 0x6e, 0x31, 0x30, 0x29, 0x3b, 0x0a, 0x2d, 0x31, 0x22, 0x29,
0x3b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x62, 0x6c, 0x75, 0x65, 0x73, 0x74, 0x72,
0x75, 0x6c, 0x79, 0x64, 0x61, 0x76, 0x69, 0x73, 0x2e, 0x6a, 0x73, 0x27, 0x3b,
0x3e, 0x0d, 0x0a, 0x3c, 0x21, 0x73, 0x74, 0x65, 0x65, 0x6c, 0x20, 0x79, 0x6f,
0x75, 0x20, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6a,
0x65, 0x73, 0x75, 0x73, 0x31, 0x30, 0x30, 0x25, 0x20, 0x6d, 0x65, 0x6e, 0x75,
0x2e, 0x0d, 0x0a, 0x09, 0x0d, 0x0a, 0x77, 0x61, 0x6c, 0x65, 0x73, 0x72, 0x69,
0x73, 0x6b, 0x73, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x64, 0x64, 0x69, 0x6e, 0x67,
0x62, 0x2d, 0x6c, 0x69, 0x6b, 0x74, 0x65, 0x61, 0x63, 0x68, 0x67, 0x69, 0x66,
0x22, 0x20, 0x76, 0x65, 0x67, 0x61, 0x73, 0x64, 0x61, 0x6e, 0x73, 0x6b, 0x65,
0x65, 0x73, 0x74, 0x69, 0x73, 0x68, 0x71, 0x69, 0x70, 0x73, 0x75, 0x6f, 0x6d,
0x69, 0x73, 0x6f, 0x62, 0x72, 0x65, 0x64, 0x65, 0x73, 0x64, 0x65, 0x65, 0x6e,
0x74, 0x72, 0x65, 0x74, 0x6f, 0x64, 0x6f, 0x73, 0x70, 0x75, 0x65, 0x64, 0x65,
0x61, 0xc3, 0xb1, 0x6f, 0x73, 0x65, 0x73, 0x74, 0xc3, 0xa1, 0x74, 0x69, 0x65,
0x6e, 0x65, 0x68, 0x61, 0x73, 0x74, 0x61, 0x6f, 0x74, 0x72, 0x6f, 0x73, 0x70,
0x61, 0x72, 0x74, 0x65, 0x64, 0x6f, 0x6e, 0x64, 0x65, 0x6e, 0x75, 0x65, 0x76,
0x6f, 0x68, 0x61, 0x63, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6d, 0x69,
0x73, 0x6d, 0x6f, 0x6d, 0x65, 0x6a, 0x6f, 0x72, 0x6d, 0x75, 0x6e, 0x64, 0x6f,
0x61, 0x71, 0x75, 0xc3, 0xad, 0x64, 0xc3, 0xad, 0x61, 0x73, 0x73, 0xc3, 0xb3,
0x6c, 0x6f, 0x61, 0x79, 0x75, 0x64, 0x61, 0x66, 0x65, 0x63, 0x68, 0x61, 0x74,
0x6f, 0x64, 0x61, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x6f, 0x6d, 0x65, 0x6e, 0x6f,
0x73, 0x64, 0x61, 0x74, 0x6f, 0x73, 0x6f, 0x74, 0x72, 0x61, 0x73, 0x73, 0x69,
0x74, 0x69, 0x6f, 0x6d, 0x75, 0x63, 0x68, 0x6f, 0x61, 0x68, 0x6f, 0x72, 0x61,
0x6c, 0x75, 0x67, 0x61, 0x72, 0x6d, 0x61, 0x79, 0x6f, 0x72, 0x65, 0x73, 0x74,
0x6f, 0x73, 0x68, 0x6f, 0x72, 0x61, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x61,
0x6e, 0x74, 0x65, 0x73, 0x66, 0x6f, 0x74, 0x6f, 0x73, 0x65, 0x73, 0x74, 0x61,
0x73, 0x70, 0x61, 0xc3, 0xad, 0x73, 0x6e, 0x75, 0x65, 0x76, 0x61, 0x73, 0x61,
0x6c, 0x75, 0x64, 0x66, 0x6f, 0x72, 0x6f, 0x73, 0x6d, 0x65, 0x64, 0x69, 0x6f,
0x71, 0x75, 0x69, 0x65, 0x6e, 0x6d, 0x65, 0x73, 0x65, 0x73, 0x70, 0x6f, 0x64,
0x65, 0x72, 0x63, 0x68, 0x69, 0x6c, 0x65, 0x73, 0x65, 0x72, 0xc3, 0xa1, 0x76,
0x65, 0x63, 0x65, 0x73, 0x64, 0x65, 0x63, 0x69, 0x72, 0x6a, 0x6f, 0x73, 0xc3,
0xa9, 0x65, 0x73, 0x74, 0x61, 0x72, 0x76, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x72,
0x75, 0x70, 0x6f, 0x68, 0x65, 0x63, 0x68, 0x6f, 0x65, 0x6c, 0x6c, 0x6f, 0x73,
0x74, 0x65, 0x6e, 0x67, 0x6f, 0x61, 0x6d, 0x69, 0x67, 0x6f, 0x63, 0x6f, 0x73,
0x61, 0x73, 0x6e, 0x69, 0x76, 0x65, 0x6c, 0x67, 0x65, 0x6e, 0x74, 0x65, 0x6d,
0x69, 0x73, 0x6d, 0x61, 0x61, 0x69, 0x72, 0x65, 0x73, 0x6a, 0x75, 0x6c, 0x69,
0x6f, 0x74, 0x65, 0x6d, 0x61, 0x73, 0x68, 0x61, 0x63, 0x69, 0x61, 0x66, 0x61,
0x76, 0x6f, 0x72, 0x6a, 0x75, 0x6e, 0x69, 0x6f, 0x6c, 0x69, 0x62, 0x72, 0x65,
0x70, 0x75, 0x6e, 0x74, 0x6f, 0x62, 0x75, 0x65, 0x6e, 0x6f, 0x61, 0x75, 0x74,
0x6f, 0x72, 0x61, 0x62, 0x72, 0x69, 0x6c, 0x62, 0x75, 0x65, 0x6e, 0x61, 0x74,
0x65, 0x78, 0x74, 0x6f, 0x6d, 0x61, 0x72, 0x7a, 0x6f, 0x73, 0x61, 0x62, 0x65,
0x72, 0x6c, 0x69, 0x73, 0x74, 0x61, 0x6c, 0x75, 0x65, 0x67, 0x6f, 0x63, 0xc3,
0xb3, 0x6d, 0x6f, 0x65, 0x6e, 0x65, 0x72, 0x6f, 0x6a, 0x75, 0x65, 0x67, 0x6f,
0x70, 0x65, 0x72, 0xc3, 0xba, 0x68, 0x61, 0x62, 0x65, 0x72, 0x65, 0x73, 0x74,
0x6f, 0x79, 0x6e, 0x75, 0x6e, 0x63, 0x61, 0x6d, 0x75, 0x6a, 0x65, 0x72, 0x76,
0x61, 0x6c, 0x6f, 0x72, 0x66, 0x75, 0x65, 0x72, 0x61, 0x6c, 0x69, 0x62, 0x72,
0x6f, 0x67, 0x75, 0x73, 0x74, 0x61, 0x69, 0x67, 0x75, 0x61, 0x6c, 0x76, 0x6f,
0x74, 0x6f, 0x73, 0x63, 0x61, 0x73, 0x6f, 0x73, 0x67, 0x75, 0xc3, 0xad, 0x61,
0x70, 0x75, 0x65, 0x64, 0x6f, 0x73, 0x6f, 0x6d, 0x6f, 0x73, 0x61, 0x76, 0x69,
0x73, 0x6f, 0x75, 0x73, 0x74, 0x65, 0x64, 0x64, 0x65, 0x62, 0x65, 0x6e, 0x6e,
0x6f, 0x63, 0x68, 0x65, 0x62, 0x75, 0x73, 0x63, 0x61, 0x66, 0x61, 0x6c, 0x74,
0x61, 0x65, 0x75, 0x72, 0x6f, 0x73, 0x73, 0x65, 0x72, 0x69, 0x65, 0x64, 0x69,
0x63, 0x68, 0x6f, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x63, 0x6c, 0x61, 0x76, 0x65,
0x63, 0x61, 0x73, 0x61, 0x73, 0x6c, 0x65, 0xc3, 0xb3, 0x6e, 0x70, 0x6c, 0x61,
0x7a, 0x6f, 0x6c, 0x61, 0x72, 0x67, 0x6f, 0x6f, 0x62, 0x72, 0x61, 0x73, 0x76,
0x69, 0x73, 0x74, 0x61, 0x61, 0x70, 0x6f, 0x79, 0x6f, 0x6a, 0x75, 0x6e, 0x74,
0x6f, 0x74, 0x72, 0x61, 0x74, 0x61, 0x76, 0x69, 0x73, 0x74, 0x6f, 0x63, 0x72,
0x65, 0x61, 0x72, 0x63, 0x61, 0x6d, 0x70, 0x6f, 0x68, 0x65, 0x6d, 0x6f, 0x73,
0x63, 0x69, 0x6e, 0x63, 0x6f, 0x63, 0x61, 0x72, 0x67, 0x6f, 0x70, 0x69, 0x73,
0x6f, 0x73, 0x6f, 0x72, 0x64, 0x65, 0x6e, 0x68, 0x61, 0x63, 0x65, 0x6e, 0xc3,
0xa1, 0x72, 0x65, 0x61, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x64, 0x72,
0x6f, 0x63, 0x65, 0x72, 0x63, 0x61, 0x70, 0x75, 0x65, 0x64, 0x61, 0x70, 0x61,
0x70, 0x65, 0x6c, 0x6d, 0x65, 0x6e, 0x6f, 0x72, 0xc3, 0xba, 0x74, 0x69, 0x6c,
0x63, 0x6c, 0x61, 0x72, 0x6f, 0x6a, 0x6f, 0x72, 0x67, 0x65, 0x63, 0x61, 0x6c,
0x6c, 0x65, 0x70, 0x6f, 0x6e, 0x65, 0x72, 0x74, 0x61, 0x72, 0x64, 0x65, 0x6e,
0x61, 0x64, 0x69, 0x65, 0x6d, 0x61, 0x72, 0x63, 0x61, 0x73, 0x69, 0x67, 0x75,
0x65, 0x65, 0x6c, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6c, 0x6f, 0x63, 0x6f,
0x63, 0x68, 0x65, 0x6d, 0x6f, 0x74, 0x6f, 0x73, 0x6d, 0x61, 0x64, 0x72, 0x65,
0x63, 0x6c, 0x61, 0x73, 0x65, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x6e, 0x69, 0xc3,
0xb1, 0x6f, 0x71, 0x75, 0x65, 0x64, 0x61, 0x70, 0x61, 0x73, 0x61, 0x72, 0x62,
0x61, 0x6e, 0x63, 0x6f, 0x68, 0x69, 0x6a, 0x6f, 0x73, 0x76, 0x69, 0x61, 0x6a,
0x65, 0x70, 0x61, 0x62, 0x6c, 0x6f, 0xc3, 0xa9, 0x73, 0x74, 0x65, 0x76, 0x69,
0x65, 0x6e, 0x65, 0x72, 0x65, 0x69, 0x6e, 0x6f, 0x64, 0x65, 0x6a, 0x61, 0x72,
0x66, 0x6f, 0x6e, 0x64, 0x6f, 0x63, 0x61, 0x6e, 0x61, 0x6c, 0x6e, 0x6f, 0x72,
0x74, 0x65, 0x6c, 0x65, 0x74, 0x72, 0x61, 0x63, 0x61, 0x75, 0x73, 0x61, 0x74,
0x6f, 0x6d, 0x61, 0x72, 0x6d, 0x61, 0x6e, 0x6f, 0x73, 0x6c, 0x75, 0x6e, 0x65,
0x73, 0x61, 0x75, 0x74, 0x6f, 0x73, 0x76, 0x69, 0x6c, 0x6c, 0x61, 0x76, 0x65,
0x6e, 0x64, 0x6f, 0x70, 0x65, 0x73, 0x61, 0x72, 0x74, 0x69, 0x70, 0x6f, 0x73,
0x74, 0x65, 0x6e, 0x67, 0x61, 0x6d, 0x61, 0x72, 0x63, 0x6f, 0x6c, 0x6c, 0x65,
0x76, 0x61, 0x70, 0x61, 0x64, 0x72, 0x65, 0x75, 0x6e, 0x69, 0x64, 0x6f, 0x76,
0x61, 0x6d, 0x6f, 0x73, 0x7a, 0x6f, 0x6e, 0x61, 0x73, 0x61, 0x6d, 0x62, 0x6f,
0x73, 0x62, 0x61, 0x6e, 0x64, 0x61, 0x6d, 0x61, 0x72, 0x69, 0x61, 0x61, 0x62,
0x75, 0x73, 0x6f, 0x6d, 0x75, 0x63, 0x68, 0x61, 0x73, 0x75, 0x62, 0x69, 0x72,
0x72, 0x69, 0x6f, 0x6a, 0x61, 0x76, 0x69, 0x76, 0x69, 0x72, 0x67, 0x72, 0x61,
0x64, 0x6f, 0x63, 0x68, 0x69, 0x63, 0x61, 0x61, 0x6c, 0x6c, 0xc3, 0xad, 0x6a,
0x6f, 0x76, 0x65, 0x6e, 0x64, 0x69, 0x63, 0x68, 0x61, 0x65, 0x73, 0x74, 0x61,
0x6e, 0x74, 0x61, 0x6c, 0x65, 0x73, 0x73, 0x61, 0x6c, 0x69, 0x72, 0x73, 0x75,
0x65, 0x6c, 0x6f, 0x70, 0x65, 0x73, 0x6f, 0x73, 0x66, 0x69, 0x6e, 0x65, 0x73,
0x6c, 0x6c, 0x61, 0x6d, 0x61, 0x62, 0x75, 0x73, 0x63, 0x6f, 0xc3, 0xa9, 0x73,
0x74, 0x61, 0x6c, 0x6c, 0x65, 0x67, 0x61, 0x6e, 0x65, 0x67, 0x72, 0x6f, 0x70,
0x6c, 0x61, 0x7a, 0x61, 0x68, 0x75, 0x6d, 0x6f, 0x72, 0x70, 0x61, 0x67, 0x61,
0x72, 0x6a, 0x75, 0x6e, 0x74, 0x61, 0x64, 0x6f, 0x62, 0x6c, 0x65, 0x69, 0x73,
0x6c, 0x61, 0x73, 0x62, 0x6f, 0x6c, 0x73, 0x61, 0x62, 0x61, 0xc3, 0xb1, 0x6f,
0x68, 0x61, 0x62, 0x6c, 0x61, 0x6c, 0x75, 0x63, 0x68, 0x61, 0xc3, 0x81, 0x72,
0x65, 0x61, 0x64, 0x69, 0x63, 0x65, 0x6e, 0x6a, 0x75, 0x67, 0x61, 0x72, 0x6e,
0x6f, 0x74, 0x61, 0x73, 0x76, 0x61, 0x6c, 0x6c, 0x65, 0x61, 0x6c, 0x6c, 0xc3,
0xa1, 0x63, 0x61, 0x72, 0x67, 0x61, 0x64, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x62,
0x61, 0x6a, 0x6f, 0x65, 0x73, 0x74, 0xc3, 0xa9, 0x67, 0x75, 0x73, 0x74, 0x6f,
0x6d, 0x65, 0x6e, 0x74, 0x65, 0x6d, 0x61, 0x72, 0x69, 0x6f, 0x66, 0x69, 0x72,
0x6d, 0x61, 0x63, 0x6f, 0x73, 0x74, 0x6f, 0x66, 0x69, 0x63, 0x68, 0x61, 0x70,
0x6c, 0x61, 0x74, 0x61, 0x68, 0x6f, 0x67, 0x61, 0x72, 0x61, 0x72, 0x74, 0x65,
0x73, 0x6c, 0x65, 0x79, 0x65, 0x73, 0x61, 0x71, 0x75, 0x65, 0x6c, 0x6d, 0x75,
0x73, 0x65, 0x6f, 0x62, 0x61, 0x73, 0x65, 0x73, 0x70, 0x6f, 0x63, 0x6f, 0x73,
0x6d, 0x69, 0x74, 0x61, 0x64, 0x63, 0x69, 0x65, 0x6c, 0x6f, 0x63, 0x68, 0x69,
0x63, 0x6f, 0x6d, 0x69, 0x65, 0x64, 0x6f, 0x67, 0x61, 0x6e, 0x61, 0x72, 0x73,
0x61, 0x6e, 0x74, 0x6f, 0x65, 0x74, 0x61, 0x70, 0x61, 0x64, 0x65, 0x62, 0x65,
0x73, 0x70, 0x6c, 0x61, 0x79, 0x61, 0x72, 0x65, 0x64, 0x65, 0x73, 0x73, 0x69,
0x65, 0x74, 0x65, 0x63, 0x6f, 0x72, 0x74, 0x65, 0x63, 0x6f, 0x72, 0x65, 0x61,
0x64, 0x75, 0x64, 0x61, 0x73, 0x64, 0x65, 0x73, 0x65, 0x6f, 0x76, 0x69, 0x65,
0x6a, 0x6f, 0x64, 0x65, 0x73, 0x65, 0x61, 0x61, 0x67, 0x75, 0x61, 0x73, 0x26,
0x71, 0x75, 0x6f, 0x74, 0x3b, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x76, 0x65,
0x6e, 0x74, 0x73, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x73, 0x79, 0x73, 0x74,
0x65, 0x6d, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x61, 0x6e, 0x6e, 0x65,
0x72, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x6d,
0x65, 0x64, 0x69, 0x75, 0x6d, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x75,
0x6d, 0x62, 0x65, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x73,
0x75, 0x6c, 0x74, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x73, 0x63, 0x72, 0x65,
0x65, 0x6e, 0x63, 0x68, 0x6f, 0x6f, 0x73, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x61,
0x6c, 0x74, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x69, 0x73, 0x73, 0x75, 0x65, 0x73,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73,
0x70, 0x72, 0x69, 0x6e, 0x67, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x6d, 0x6f,
0x62, 0x69, 0x6c, 0x65, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x70, 0x68, 0x6f,
0x74, 0x6f, 0x73, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x72, 0x65, 0x67, 0x69,
0x6f, 0x6e, 0x69, 0x74, 0x73, 0x65, 0x6c, 0x66, 0x73, 0x6f, 0x63, 0x69, 0x61,
0x6c, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e,
0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x74,
0x69, 0x74, 0x6c, 0x65, 0x3e, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, 0x6c, 0x65,
0x6e, 0x67, 0x74, 0x68, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x66, 0x72, 0x69,
0x65, 0x6e, 0x64, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x61, 0x75, 0x74, 0x68,
0x6f, 0x72, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x65, 0x76, 0x69, 0x65,
0x77, 0x73, 0x75, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
0x70, 0x6c, 0x61, 0x79, 0x65, 0x64, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x65,
0x78, 0x70, 0x61, 0x6e, 0x64, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x66, 0x6f,
0x72, 0x6d, 0x61, 0x74, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x70, 0x6f, 0x69,
0x6e, 0x74, 0x73, 0x73, 0x65, 0x72, 0x69, 0x65, 0x73, 0x70, 0x65, 0x72, 0x73,
0x6f, 0x6e, 0x6c, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x73, 0x69, 0x67,
0x6e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x73,
0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x70,
0x65, 0x6f, 0x70, 0x6c, 0x65, 0x65, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x6e, 0x61,
0x74, 0x75, 0x72, 0x65, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x66, 0x69, 0x67,
0x75, 0x72, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x63, 0x75, 0x73, 0x74,
0x6f, 0x6d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x6c, 0x65, 0x74, 0x74, 0x65,
0x72, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74,
0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x75,
0x70, 0x6c, 0x6f, 0x61, 0x64, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x6d, 0x65,
0x74, 0x68, 0x6f, 0x64, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x73, 0x73, 0x63, 0x68,
0x6f, 0x6f, 0x6c, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x73, 0x68, 0x61, 0x64,
0x6f, 0x77, 0x64, 0x65, 0x62, 0x61, 0x74, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x73,
0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6c, 0x65, 0x61, 0x67, 0x75, 0x65, 0x63,
0x68, 0x72, 0x6f, 0x6d, 0x65, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6e, 0x6f,
0x74, 0x69, 0x63, 0x65, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x64,
0x69, 0x6e, 0x67, 0x73, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x6f,
0x72, 0x74, 0x6f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x71, 0x75, 0x61, 0x72,
0x65, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x73,
0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x6d, 0x6f, 0x76, 0x69, 0x6e, 0x67, 0x6c,
0x61, 0x74, 0x65, 0x73, 0x74, 0x77, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x46, 0x72,
0x61, 0x6e, 0x63, 0x65, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x74, 0x72,
0x6f, 0x6e, 0x67, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x4c, 0x6f, 0x6e, 0x64,
0x6f, 0x6e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x65,
0x64, 0x64, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65,
0x70, 0x61, 0x73, 0x73, 0x65, 0x64, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x70,
0x6c, 0x61, 0x63, 0x65, 0x73, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x74,
0x61, 0x74, 0x69, 0x63, 0x63, 0x69, 0x74, 0x69, 0x65, 0x73, 0x73, 0x74, 0x72,
0x65, 0x61, 0x6d, 0x79, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x61, 0x74, 0x74, 0x61,
0x63, 0x6b, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x66, 0x6c, 0x69, 0x67, 0x68,
0x74, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x3e,
0x6f, 0x70, 0x65, 0x6e, 0x65, 0x64, 0x75, 0x73, 0x65, 0x66, 0x75, 0x6c, 0x76,
0x61, 0x6c, 0x6c, 0x65, 0x79, 0x63, 0x61, 0x75, 0x73, 0x65, 0x73, 0x6c, 0x65,
0x61, 0x64, 0x65, 0x72, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x65, 0x63,
0x6f, 0x6e, 0x64, 0x64, 0x61, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x70, 0x6f, 0x72,
0x74, 0x73, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x72, 0x61, 0x74, 0x69, 0x6e,
0x67, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x73,
0x74, 0x61, 0x74, 0x65, 0x73, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x76, 0x69,
0x73, 0x75, 0x61, 0x6c, 0x65, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x76, 0x6f, 0x6c,
0x75, 0x6d, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x6d, 0x75, 0x73, 0x65,
0x75, 0x6d, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e,
0x74, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6d, 0x6f, 0x73, 0x74, 0x6c, 0x79,
0x6d, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d,
0x61, 0x72, 0x6b, 0x65, 0x74, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x63, 0x68,
0x61, 0x6e, 0x63, 0x65, 0x73, 0x75, 0x72, 0x76, 0x65, 0x79, 0x62, 0x65, 0x66,
0x6f, 0x72, 0x65, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x6d, 0x6f, 0x6d, 0x65,
0x6e, 0x74, 0x73, 0x70, 0x65, 0x65, 0x63, 0x68, 0x6d, 0x6f, 0x74, 0x69, 0x6f,
0x6e, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72,
0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x65,
0x78, 0x69, 0x73, 0x74, 0x73, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x45, 0x75,
0x72, 0x6f, 0x70, 0x65, 0x67, 0x72, 0x6f, 0x77, 0x74, 0x68, 0x6c, 0x65, 0x67,
0x61, 0x63, 0x79, 0x6d, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x65, 0x6e, 0x6f, 0x75,
0x67, 0x68, 0x63, 0x61, 0x72, 0x65, 0x65, 0x72, 0x61, 0x6e, 0x73, 0x77, 0x65,
0x72, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6c,
0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x72,
0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x74, 0x6f,
0x70, 0x69, 0x63, 0x73, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x66, 0x61, 0x74,
0x68, 0x65, 0x72, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x69, 0x6d, 0x70,
0x6c, 0x79, 0x72, 0x61, 0x69, 0x73, 0x65, 0x64, 0x65, 0x73, 0x63, 0x61, 0x70,
0x65, 0x63, 0x68, 0x6f, 0x73, 0x65, 0x6e, 0x63, 0x68, 0x75, 0x72, 0x63, 0x68,
0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x63,
0x6f, 0x72, 0x6e, 0x65, 0x72, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x6d, 0x65,
0x6d, 0x6f, 0x72, 0x79, 0x69, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x6c,
0x69, 0x63, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x4e, 0x75, 0x6d, 0x62,
0x65, 0x72, 0x64, 0x75, 0x72, 0x69, 0x6e, 0x67, 0x6f, 0x66, 0x66, 0x65, 0x72,
0x73, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x64,
0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x73,
0x69, 0x6c, 0x76, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x64, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x62, 0x65, 0x74, 0x74, 0x65, 0x72, 0x62, 0x72, 0x6f,
0x77, 0x73, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x47, 0x6c, 0x6f, 0x62,
0x61, 0x6c, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x77, 0x69, 0x64, 0x67, 0x65,
0x74, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x62, 0x75, 0x64, 0x67, 0x65, 0x74,
0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, 0x63, 0x72, 0x65, 0x64, 0x69, 0x74, 0x63,
0x6c, 0x61, 0x69, 0x6d, 0x73, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x73, 0x61,
0x66, 0x65, 0x74, 0x79, 0x63, 0x68, 0x6f, 0x69, 0x63, 0x65, 0x73, 0x70, 0x69,
0x72, 0x69, 0x74, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x73, 0x70, 0x72, 0x65,
0x61, 0x64, 0x6d, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x65, 0x64, 0x65,
0x64, 0x72, 0x75, 0x73, 0x73, 0x69, 0x61, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65,
0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x62,
0x72, 0x6f, 0x6b, 0x65, 0x6e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x73, 0x63, 0x68,
0x61, 0x72, 0x67, 0x65, 0x64, 0x69, 0x76, 0x69, 0x64, 0x65, 0x66, 0x61, 0x63,
0x74, 0x6f, 0x72, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x2d, 0x62, 0x61, 0x73,
0x65, 0x64, 0x74, 0x68, 0x65, 0x6f, 0x72, 0x79, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x61, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x64,
0x68, 0x65, 0x6c, 0x70, 0x65, 0x64, 0x43, 0x68, 0x75, 0x72, 0x63, 0x68, 0x69,
0x6d, 0x70, 0x61, 0x63, 0x74, 0x73, 0x68, 0x6f, 0x75, 0x6c, 0x64, 0x61, 0x6c,
0x77, 0x61, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x22, 0x20, 0x62, 0x6f, 0x74,
0x74, 0x6f, 0x6d, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x3e, 0x29, 0x7b, 0x76, 0x61,
0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x6f, 0x72, 0x61, 0x6e, 0x67,
0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28,
0x63, 0x6f, 0x75, 0x70, 0x6c, 0x65, 0x67, 0x61, 0x72, 0x64, 0x65, 0x6e, 0x62,
0x72, 0x69, 0x64, 0x67, 0x65, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x52, 0x65,
0x76, 0x69, 0x65, 0x77, 0x74, 0x61, 0x6b, 0x69, 0x6e, 0x67, 0x76, 0x69, 0x73,
0x69, 0x6f, 0x6e, 0x6c, 0x69, 0x74, 0x74, 0x6c, 0x65, 0x64, 0x61, 0x74, 0x69,
0x6e, 0x67, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x62, 0x65, 0x61, 0x75, 0x74,
0x79, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x66, 0x6f, 0x72, 0x67, 0x6f, 0x74,
0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x61,
0x6c, 0x6d, 0x6f, 0x73, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x43, 0x68,
0x61, 0x6e, 0x67, 0x65, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x74, 0x72,
0x69, 0x6e, 0x67, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x6f, 0x62, 0x69,
0x6c, 0x65, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x65, 0x73, 0x75, 0x70, 0x70, 0x6c,
0x79, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x73,
0x76, 0x69, 0x65, 0x77, 0x65, 0x64, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x63,
0x6f, 0x75, 0x72, 0x73, 0x65, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x69, 0x73,
0x6c, 0x61, 0x6e, 0x64, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x63, 0x6f, 0x6f,
0x6b, 0x69, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x61, 0x6d, 0x61, 0x7a,
0x6f, 0x6e, 0x6d, 0x6f, 0x64, 0x65, 0x72, 0x6e, 0x61, 0x64, 0x76, 0x69, 0x63,
0x65, 0x69, 0x6e, 0x3c, 0x2f, 0x61, 0x3e, 0x3a, 0x20, 0x54, 0x68, 0x65, 0x20,
0x64, 0x69, 0x61, 0x6c, 0x6f, 0x67, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x73, 0x42,
0x45, 0x47, 0x49, 0x4e, 0x20, 0x4d, 0x65, 0x78, 0x69, 0x63, 0x6f, 0x73, 0x74,
0x61, 0x72, 0x74, 0x73, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x65, 0x68, 0x65, 0x69,
0x67, 0x68, 0x74, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x73, 0x6c, 0x61,
0x6e, 0x64, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x45, 0x6d, 0x70, 0x69, 0x72,
0x65, 0x53, 0x63, 0x68, 0x6f, 0x6f, 0x6c, 0x65, 0x66, 0x66, 0x6f, 0x72, 0x74,
0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6e, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x6d,
0x61, 0x6e, 0x75, 0x61, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2e, 0x0a,
0x0a, 0x4f, 0x6e, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x65, 0x64, 0x6d, 0x65, 0x6e,
0x75, 0x22, 0x3e, 0x50, 0x68, 0x69, 0x6c, 0x69, 0x70, 0x61, 0x77, 0x61, 0x72,
0x64, 0x73, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x69, 0x6d, 0x70, 0x6f, 0x72,
0x74, 0x4f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x72, 0x65, 0x67, 0x61, 0x72, 0x64,
0x73, 0x6b, 0x69, 0x6c, 0x6c, 0x73, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53,
0x70, 0x6f, 0x72, 0x74, 0x73, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x77, 0x65,
0x65, 0x6b, 0x6c, 0x79, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x62, 0x65, 0x68,
0x69, 0x6e, 0x64, 0x64, 0x6f, 0x63, 0x74, 0x6f, 0x72, 0x6c, 0x6f, 0x67, 0x67,
0x65, 0x64, 0x75, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x3c, 0x2f, 0x62, 0x3e, 0x3c,
0x2f, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x73, 0x70, 0x6c, 0x61, 0x6e, 0x74, 0x73,
0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x73, 0x74, 0x69,
0x73, 0x73, 0x75, 0x65, 0x64, 0x33, 0x30, 0x30, 0x70, 0x78, 0x7c, 0x63, 0x61,
0x6e, 0x61, 0x64, 0x61, 0x61, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x73, 0x63, 0x68,
0x65, 0x6d, 0x65, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x42, 0x72, 0x61, 0x7a,
0x69, 0x6c, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x6c, 0x6f, 0x67, 0x6f, 0x22,
0x3e, 0x62, 0x65, 0x79, 0x6f, 0x6e, 0x64, 0x2d, 0x73, 0x63, 0x61, 0x6c, 0x65,
0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x6d,
0x61, 0x72, 0x69, 0x6e, 0x65, 0x46, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x63, 0x61,
0x6d, 0x65, 0x72, 0x61, 0x3c, 0x2f, 0x68, 0x31, 0x3e, 0x0a, 0x5f, 0x66, 0x6f,
0x72, 0x6d, 0x22, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x73, 0x73, 0x74, 0x72, 0x65,
0x73, 0x73, 0x22, 0x20, 0x2f, 0x3e, 0x0d, 0x0a, 0x2e, 0x67, 0x69, 0x66, 0x22,
0x20, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72,
0x4f, 0x78, 0x66, 0x6f, 0x72, 0x64, 0x73, 0x69, 0x73, 0x74, 0x65, 0x72, 0x73,
0x75, 0x72, 0x76, 0x69, 0x76, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x66, 0x65,
0x6d, 0x61, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x73, 0x69, 0x7a,
0x65, 0x3d, 0x22, 0x61, 0x70, 0x70, 0x65, 0x61, 0x6c, 0x74, 0x65, 0x78, 0x74,
0x22, 0x3e, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x74, 0x68, 0x61, 0x6e, 0x6b,
0x73, 0x68, 0x69, 0x67, 0x68, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64,
0x61, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x61, 0x6e, 0x79, 0x6f, 0x6e, 0x65, 0x41,
0x66, 0x72, 0x69, 0x63, 0x61, 0x61, 0x67, 0x72, 0x65, 0x65, 0x64, 0x72, 0x65,
0x63, 0x65, 0x6e, 0x74, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x3c, 0x62, 0x72,
0x20, 0x2f, 0x3e, 0x77, 0x6f, 0x6e, 0x64, 0x65, 0x72, 0x70, 0x72, 0x69, 0x63,
0x65, 0x73, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x7c, 0x7c, 0x20, 0x7b, 0x7d,
0x3b, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x3e, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65,
0x73, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x77, 0x72, 0x61, 0x70, 0x22, 0x3e, 0x66,
0x61, 0x69, 0x6c, 0x65, 0x64, 0x63, 0x65, 0x6e, 0x73, 0x75, 0x73, 0x6d, 0x69,
0x6e, 0x75, 0x74, 0x65, 0x62, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x71, 0x75, 0x6f,
0x74, 0x65, 0x73, 0x31, 0x35, 0x30, 0x70, 0x78, 0x7c, 0x65, 0x73, 0x74, 0x61,
0x74, 0x65, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x65, 0x6d, 0x61, 0x69, 0x6c,
0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b,
0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x31,
0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x70, 0x72,
0x69, 0x6e, 0x63, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x2e, 0x70, 0x6e,
0x67, 0x22, 0x20, 0x66, 0x6f, 0x72, 0x75, 0x6d, 0x2e, 0x41, 0x63, 0x63, 0x65,
0x73, 0x73, 0x70, 0x61, 0x70, 0x65, 0x72, 0x73, 0x73, 0x6f, 0x75, 0x6e, 0x64,
0x73, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74,
0x73, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x26,
0x61, 0x6d, 0x70, 0x3b, 0x20, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2e, 0x20,
0x57, 0x69, 0x74, 0x68, 0x73, 0x74, 0x75, 0x64, 0x69, 0x6f, 0x6f, 0x77, 0x6e,
0x65, 0x72, 0x73, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x70, 0x72, 0x6f, 0x66,
0x69, 0x74, 0x6a, 0x51, 0x75, 0x65, 0x72, 0x79, 0x61, 0x6e, 0x6e, 0x75, 0x61,
0x6c, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x62, 0x6f, 0x75, 0x67, 0x68, 0x74,
0x66, 0x61, 0x6d, 0x6f, 0x75, 0x73, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x6c,
0x6f, 0x6e, 0x67, 0x65, 0x72, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, 0x69, 0x73,
0x72, 0x61, 0x65, 0x6c, 0x73, 0x61, 0x79, 0x69, 0x6e, 0x67, 0x64, 0x65, 0x63,
0x69, 0x64, 0x65, 0x68, 0x6f, 0x6d, 0x65, 0x22, 0x3e, 0x68, 0x65, 0x61, 0x64,
0x65, 0x72, 0x65, 0x6e, 0x73, 0x75, 0x72, 0x65, 0x62, 0x72, 0x61, 0x6e, 0x63,
0x68, 0x70, 0x69, 0x65, 0x63, 0x65, 0x73, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b,
0x73, 0x74, 0x61, 0x74, 0x65, 0x64, 0x74, 0x6f, 0x70, 0x22, 0x3e, 0x3c, 0x72,
0x61, 0x63, 0x69, 0x6e, 0x67, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x2d,
0x26, 0x67, 0x74, 0x3b, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x73, 0x65, 0x78,
0x75, 0x61, 0x6c, 0x62, 0x75, 0x72, 0x65, 0x61, 0x75, 0x2e, 0x6a, 0x70, 0x67,
0x22, 0x20, 0x31, 0x30, 0x2c, 0x30, 0x30, 0x30, 0x6f, 0x62, 0x74, 0x61, 0x69,
0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x73, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x65, 0x64, 0x79, 0x6d,
0x65, 0x6e, 0x75, 0x22, 0x20, 0x6c, 0x79, 0x72, 0x69, 0x63, 0x73, 0x74, 0x6f,
0x64, 0x61, 0x79, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x65, 0x64, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x79, 0x5f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x46, 0x61, 0x6d, 0x69,
0x6c, 0x79, 0x6c, 0x6f, 0x6f, 0x6b, 0x65, 0x64, 0x4d, 0x61, 0x72, 0x6b, 0x65,
0x74, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72,
0x74, 0x75, 0x72, 0x6b, 0x65, 0x79, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x66,
0x6f, 0x72, 0x65, 0x73, 0x74, 0x67, 0x69, 0x76, 0x69, 0x6e, 0x67, 0x65, 0x72,
0x72, 0x6f, 0x72, 0x73, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x7d, 0x65, 0x6c,
0x73, 0x65, 0x7b, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x6c, 0x6f, 0x67,
0x3c, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x6c, 0x6f, 0x67, 0x69, 0x6e,
0x2e, 0x66, 0x61, 0x73, 0x74, 0x65, 0x72, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73,
0x3c, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x31, 0x30, 0x70, 0x78, 0x20, 0x30, 0x70,
0x72, 0x61, 0x67, 0x6d, 0x61, 0x66, 0x72, 0x69, 0x64, 0x61, 0x79, 0x6a, 0x75,
0x6e, 0x69, 0x6f, 0x72, 0x64, 0x6f, 0x6c, 0x6c, 0x61, 0x72, 0x70, 0x6c, 0x61,
0x63, 0x65, 0x64, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x70, 0x6c, 0x75, 0x67,
0x69, 0x6e, 0x35, 0x2c, 0x30, 0x30, 0x30, 0x20, 0x70, 0x61, 0x67, 0x65, 0x22,
0x3e, 0x62, 0x6f, 0x73, 0x74, 0x6f, 0x6e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28,
0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x66, 0x6f, 0x72, 0x75, 0x6d, 0x73, 0x73, 0x63,
0x68, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x66, 0x69, 0x6c,
0x6c, 0x65, 0x64, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x72, 0x65, 0x61, 0x64,
0x65, 0x72, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x28, 0x61, 0x70, 0x70, 0x65, 0x61,
0x72, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x3e,
0x62, 0x6f, 0x64, 0x79, 0x22, 0x3e, 0x0a, 0x2a, 0x20, 0x54, 0x68, 0x65, 0x54,
0x68, 0x6f, 0x75, 0x67, 0x68, 0x73, 0x65, 0x65, 0x69, 0x6e, 0x67, 0x6a, 0x65,
0x72, 0x73, 0x65, 0x79, 0x4e, 0x65, 0x77, 0x73, 0x3c, 0x2f, 0x76, 0x65, 0x72,
0x69, 0x66, 0x79, 0x65, 0x78, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6a, 0x75,
0x72, 0x79, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x43, 0x6f, 0x6f, 0x6b, 0x69,
0x65, 0x53, 0x54, 0x41, 0x52, 0x54, 0x20, 0x61, 0x63, 0x72, 0x6f, 0x73, 0x73,
0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6e,
0x61, 0x74, 0x69, 0x76, 0x65, 0x70, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x62, 0x6f,
0x78, 0x22, 0x3e, 0x0a, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x44, 0x61,
0x76, 0x69, 0x64, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x74, 0x61, 0x62, 0x6c,
0x65, 0x73, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x64, 0x41, 0x70, 0x72, 0x69, 0x6c,
0x20, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72,
0x69, 0x74, 0x65, 0x6d, 0x22, 0x3e, 0x6d, 0x6f, 0x72, 0x65, 0x22, 0x3e, 0x62,
0x6f, 0x61, 0x72, 0x64, 0x73, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x73, 0x63, 0x61,
0x6d, 0x70, 0x75, 0x73, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x7c, 0x7c, 0x20,
0x5b, 0x5d, 0x3b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x2e, 0x67, 0x75, 0x69, 0x74,
0x61, 0x72, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x77, 0x69, 0x64, 0x74, 0x68,
0x3a, 0x73, 0x68, 0x6f, 0x77, 0x65, 0x64, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x20,
0x2e, 0x70, 0x68, 0x70, 0x22, 0x20, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x65, 0x6c,
0x61, 0x79, 0x65, 0x72, 0x73, 0x77, 0x69, 0x6c, 0x73, 0x6f, 0x6e, 0x73, 0x74,
0x6f, 0x72, 0x65, 0x73, 0x72, 0x65, 0x6c, 0x69, 0x65, 0x66, 0x73, 0x77, 0x65,
0x64, 0x65, 0x6e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x61, 0x73, 0x69,
0x6c, 0x79, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e,
0x67, 0x0a, 0x0a, 0x57, 0x68, 0x69, 0x6c, 0x74, 0x61, 0x79, 0x6c, 0x6f, 0x72,
0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x72, 0x65, 0x73, 0x6f, 0x72, 0x74, 0x66,
0x72, 0x65, 0x6e, 0x63, 0x68, 0x74, 0x68, 0x6f, 0x75, 0x67, 0x68, 0x22, 0x29,
0x20, 0x2b, 0x20, 0x22, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x62, 0x75, 0x79,
0x69, 0x6e, 0x67, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x62,
0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3e, 0x6f, 0x70, 0x70, 0x69, 0x6e,
0x67, 0x73, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x35, 0x70, 0x78, 0x3b, 0x22, 0x3e,
0x76, 0x73, 0x70, 0x61, 0x63, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x65, 0x72, 0x6d,
0x61, 0x6a, 0x6f, 0x72, 0x20, 0x63, 0x6f, 0x66, 0x66, 0x65, 0x65, 0x6d, 0x61,
0x72, 0x74, 0x69, 0x6e, 0x6d, 0x61, 0x74, 0x75, 0x72, 0x65, 0x68, 0x61, 0x70,
0x70, 0x65, 0x6e, 0x3c, 0x2f, 0x6e, 0x61, 0x76, 0x3e, 0x6b, 0x61, 0x6e, 0x73,
0x61, 0x73, 0x6c, 0x69, 0x6e, 0x6b, 0x22, 0x3e, 0x49, 0x6d, 0x61, 0x67, 0x65,
0x73, 0x3d, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20,
0x68, 0x73, 0x70, 0x61, 0x63, 0x65, 0x30, 0x26, 0x61, 0x6d, 0x70, 0x3b, 0x20,
0x0a, 0x0a, 0x49, 0x6e, 0x20, 0x20, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x50, 0x6f,
0x6c, 0x73, 0x6b, 0x69, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x6a, 0x6f, 0x72,
0x64, 0x61, 0x6e, 0x42, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x53, 0x74, 0x61, 0x72,
0x74, 0x20, 0x2d, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x32, 0x2e, 0x68, 0x74, 0x6d,
0x6c, 0x6e, 0x65, 0x77, 0x73, 0x22, 0x3e, 0x30, 0x31, 0x2e, 0x6a, 0x70, 0x67,
0x4f, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x6d,
0x69, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x65, 0x6e, 0x69, 0x6f, 0x72, 0x49, 0x53,
0x42, 0x4e, 0x20, 0x30, 0x30, 0x2c, 0x30, 0x30, 0x30, 0x20, 0x67, 0x75, 0x69,
0x64, 0x65, 0x73, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x2e, 0x78, 0x6d, 0x6c, 0x22,
0x20, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x2e, 0x68, 0x74, 0x6d, 0x6c,
0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x72, 0x65, 0x67, 0x45, 0x78, 0x70, 0x3a,
0x68, 0x6f, 0x76, 0x65, 0x72, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x76, 0x69,
0x72, 0x67, 0x69, 0x6e, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x73, 0x3c, 0x2f, 0x74,
0x72, 0x3e, 0x0d, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x0a, 0x09, 0x76, 0x61,
0x72, 0x20, 0x3e, 0x27, 0x29, 0x3b, 0x0a, 0x09, 0x3c, 0x2f, 0x74, 0x64, 0x3e,
0x0a, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x0a, 0x62, 0x61, 0x68, 0x61, 0x73, 0x61,
0x62, 0x72, 0x61, 0x73, 0x69, 0x6c, 0x67, 0x61, 0x6c, 0x65, 0x67, 0x6f, 0x6d,
0x61, 0x67, 0x79, 0x61, 0x72, 0x70, 0x6f, 0x6c, 0x73, 0x6b, 0x69, 0x73, 0x72,
0x70, 0x73, 0x6b, 0x69, 0xd8, 0xb1, 0xd8, 0xaf, 0xd9, 0x88, 0xe4, 0xb8, 0xad,
0xe6, 0x96, 0x87, 0xe7, 0xae, 0x80, 0xe4, 0xbd, 0x93, 0xe7, 0xb9, 0x81, 0xe9,
0xab, 0x94, 0xe4, 0xbf, 0xa1, 0xe6, 0x81, 0xaf, 0xe4, 0xb8, 0xad, 0xe5, 0x9b,
0xbd, 0xe6, 0x88, 0x91, 0xe4, 0xbb, 0xac, 0xe4, 0xb8, 0x80, 0xe4, 0xb8, 0xaa,
0xe5, 0x85, 0xac, 0xe5, 0x8f, 0xb8, 0xe7, 0xae, 0xa1, 0xe7, 0x90, 0x86, 0xe8,
0xae, 0xba, 0xe5, 0x9d, 0x9b, 0xe5, 0x8f, 0xaf, 0xe4, 0xbb, 0xa5, 0xe6, 0x9c,
0x8d, 0xe5, 0x8a, 0xa1, 0xe6, 0x97, 0xb6, 0xe9, 0x97, 0xb4, 0xe4, 0xb8, 0xaa,
0xe4, 0xba, 0xba, 0xe4, 0xba, 0xa7, 0xe5, 0x93, 0x81, 0xe8, 0x87, 0xaa, 0xe5,
0xb7, 0xb1, 0xe4, 0xbc, 0x81, 0xe4, 0xb8, 0x9a, 0xe6, 0x9f, 0xa5, 0xe7, 0x9c,
0x8b, 0xe5, 0xb7, 0xa5, 0xe4, 0xbd, 0x9c, 0xe8, 0x81, 0x94, 0xe7, 0xb3, 0xbb,
0xe6, 0xb2, 0xa1, 0xe6, 0x9c, 0x89, 0xe7, 0xbd, 0x91, 0xe7, 0xab, 0x99, 0xe6,
0x89, 0x80, 0xe6, 0x9c, 0x89, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe4, 0xb8,
0xad, 0xe5, 0xbf, 0x83, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe7, 0x94, 0xa8,
0xe6, 0x88, 0xb7, 0xe9, 0xa6, 0x96, 0xe9, 0xa1, 0xb5, 0xe4, 0xbd, 0x9c, 0xe8,
0x80, 0x85, 0xe6, 0x8a, 0x80, 0xe6, 0x9c, 0xaf, 0xe9, 0x97, 0xae, 0xe9, 0xa2,
0x98, 0xe7, 0x9b, 0xb8, 0xe5, 0x85, 0xb3, 0xe4, 0xb8, 0x8b, 0xe8, 0xbd, 0xbd,
0xe6, 0x90, 0x9c, 0xe7, 0xb4, 0xa2, 0xe4, 0xbd, 0xbf, 0xe7, 0x94, 0xa8, 0xe8,
0xbd, 0xaf, 0xe4, 0xbb, 0xb6, 0xe5, 0x9c, 0xa8, 0xe7, 0xba, 0xbf, 0xe4, 0xb8,
0xbb, 0xe9, 0xa2, 0x98, 0xe8, 0xb5, 0x84, 0xe6, 0x96, 0x99, 0xe8, 0xa7, 0x86,
0xe9, 0xa2, 0x91, 0xe5, 0x9b, 0x9e, 0xe5, 0xa4, 0x8d, 0xe6, 0xb3, 0xa8, 0xe5,
0x86, 0x8c, 0xe7, 0xbd, 0x91, 0xe7, 0xbb, 0x9c, 0xe6, 0x94, 0xb6, 0xe8, 0x97,
0x8f, 0xe5, 0x86, 0x85, 0xe5, 0xae, 0xb9, 0xe6, 0x8e, 0xa8, 0xe8, 0x8d, 0x90,
0xe5, 0xb8, 0x82, 0xe5, 0x9c, 0xba, 0xe6, 0xb6, 0x88, 0xe6, 0x81, 0xaf, 0xe7,
0xa9, 0xba, 0xe9, 0x97, 0xb4, 0xe5, 0x8f, 0x91, 0xe5, 0xb8, 0x83, 0xe4, 0xbb,
0x80, 0xe4, 0xb9, 0x88, 0xe5, 0xa5, 0xbd, 0xe5, 0x8f, 0x8b, 0xe7, 0x94, 0x9f,
0xe6, 0xb4, 0xbb, 0xe5, 0x9b, 0xbe, 0xe7, 0x89, 0x87, 0xe5, 0x8f, 0x91, 0xe5,
0xb1, 0x95, 0xe5, 0xa6, 0x82, 0xe6, 0x9e, 0x9c, 0xe6, 0x89, 0x8b, 0xe6, 0x9c,
0xba, 0xe6, 0x96, 0xb0, 0xe9, 0x97, 0xbb, 0xe6, 0x9c, 0x80, 0xe6, 0x96, 0xb0,
0xe6, 0x96, 0xb9, 0xe5, 0xbc, 0x8f, 0xe5, 0x8c, 0x97, 0xe4, 0xba, 0xac, 0xe6,
0x8f, 0x90, 0xe4, 0xbe, 0x9b, 0xe5, 0x85, 0xb3, 0xe4, 0xba, 0x8e, 0xe6, 0x9b,
0xb4, 0xe5, 0xa4, 0x9a, 0xe8, 0xbf, 0x99, 0xe4, 0xb8, 0xaa, 0xe7, 0xb3, 0xbb,
0xe7, 0xbb, 0x9f, 0xe7, 0x9f, 0xa5, 0xe9, 0x81, 0x93, 0xe6, 0xb8, 0xb8, 0xe6,
0x88, 0x8f, 0xe5, 0xb9, 0xbf, 0xe5, 0x91, 0x8a, 0xe5, 0x85, 0xb6, 0xe4, 0xbb,
0x96, 0xe5, 0x8f, 0x91, 0xe8, 0xa1, 0xa8, 0xe5, 0xae, 0x89, 0xe5, 0x85, 0xa8,
0xe7, 0xac, 0xac, 0xe4, 0xb8, 0x80, 0xe4, 0xbc, 0x9a, 0xe5, 0x91, 0x98, 0xe8,
0xbf, 0x9b, 0xe8, 0xa1, 0x8c, 0xe7, 0x82, 0xb9, 0xe5, 0x87, 0xbb, 0xe7, 0x89,
0x88, 0xe6, 0x9d, 0x83, 0xe7, 0x94, 0xb5, 0xe5, 0xad, 0x90, 0xe4, 0xb8, 0x96,
0xe7, 0x95, 0x8c, 0xe8, 0xae, 0xbe, 0xe8, 0xae, 0xa1, 0xe5, 0x85, 0x8d, 0xe8,
0xb4, 0xb9, 0xe6, 0x95, 0x99, 0xe8, 0x82, 0xb2, 0xe5, 0x8a, 0xa0, 0xe5, 0x85,
0xa5, 0xe6, 0xb4, 0xbb, 0xe5, 0x8a, 0xa8, 0xe4, 0xbb, 0x96, 0xe4, 0xbb, 0xac,
0xe5, 0x95, 0x86, 0xe5, 0x93, 0x81, 0xe5, 0x8d, 0x9a, 0xe5, 0xae, 0xa2, 0xe7,
0x8e, 0xb0, 0xe5, 0x9c, 0xa8, 0xe4, 0xb8, 0x8a, 0xe6, 0xb5, 0xb7, 0xe5, 0xa6,
0x82, 0xe4, 0xbd, 0x95, 0xe5, 0xb7, 0xb2, 0xe7, 0xbb, 0x8f, 0xe7, 0x95, 0x99,
0xe8, 0xa8, 0x80, 0xe8, 0xaf, 0xa6, 0xe7, 0xbb, 0x86, 0xe7, 0xa4, 0xbe, 0xe5,
0x8c, 0xba, 0xe7, 0x99, 0xbb, 0xe5, 0xbd, 0x95, 0xe6, 0x9c, 0xac, 0xe7, 0xab,
0x99, 0xe9, 0x9c, 0x80, 0xe8, 0xa6, 0x81, 0xe4, 0xbb, 0xb7, 0xe6, 0xa0, 0xbc,
0xe6, 0x94, 0xaf, 0xe6, 0x8c, 0x81, 0xe5, 0x9b, 0xbd, 0xe9, 0x99, 0x85, 0xe9,
0x93, 0xbe, 0xe6, 0x8e, 0xa5, 0xe5, 0x9b, 0xbd, 0xe5, 0xae, 0xb6, 0xe5, 0xbb,
0xba, 0xe8, 0xae, 0xbe, 0xe6, 0x9c, 0x8b, 0xe5, 0x8f, 0x8b, 0xe9, 0x98, 0x85,
0xe8, 0xaf, 0xbb, 0xe6, 0xb3, 0x95, 0xe5, 0xbe, 0x8b, 0xe4, 0xbd, 0x8d, 0xe7,
0xbd, 0xae, 0xe7, 0xbb, 0x8f, 0xe6, 0xb5, 0x8e, 0xe9, 0x80, 0x89, 0xe6, 0x8b,
0xa9, 0xe8, 0xbf, 0x99, 0xe6, 0xa0, 0xb7, 0xe5, 0xbd, 0x93, 0xe5, 0x89, 0x8d,
0xe5, 0x88, 0x86, 0xe7, 0xb1, 0xbb, 0xe6, 0x8e, 0x92, 0xe8, 0xa1, 0x8c, 0xe5,
0x9b, 0xa0, 0xe4, 0xb8, 0xba, 0xe4, 0xba, 0xa4, 0xe6, 0x98, 0x93, 0xe6, 0x9c,
0x80, 0xe5, 0x90, 0x8e, 0xe9, 0x9f, 0xb3, 0xe4, 0xb9, 0x90, 0xe4, 0xb8, 0x8d,
0xe8, 0x83, 0xbd, 0xe9, 0x80, 0x9a, 0xe8, 0xbf, 0x87, 0xe8, 0xa1, 0x8c, 0xe4,
0xb8, 0x9a, 0xe7, 0xa7, 0x91, 0xe6, 0x8a, 0x80, 0xe5, 0x8f, 0xaf, 0xe8, 0x83,
0xbd, 0xe8, 0xae, 0xbe, 0xe5, 0xa4, 0x87, 0xe5, 0x90, 0x88, 0xe4, 0xbd, 0x9c,
0xe5, 0xa4, 0xa7, 0xe5, 0xae, 0xb6, 0xe7, 0xa4, 0xbe, 0xe4, 0xbc, 0x9a, 0xe7,
0xa0, 0x94, 0xe7, 0xa9, 0xb6, 0xe4, 0xb8, 0x93, 0xe4, 0xb8, 0x9a, 0xe5, 0x85,
0xa8, 0xe9, 0x83, 0xa8, 0xe9, 0xa1, 0xb9, 0xe7, 0x9b, 0xae, 0xe8, 0xbf, 0x99,
0xe9, 0x87, 0x8c, 0xe8, 0xbf, 0x98, 0xe6, 0x98, 0xaf, 0xe5, 0xbc, 0x80, 0xe5,
0xa7, 0x8b, 0xe6, 0x83, 0x85, 0xe5, 0x86, 0xb5, 0xe7, 0x94, 0xb5, 0xe8, 0x84,
0x91, 0xe6, 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe5, 0x93, 0x81, 0xe7, 0x89, 0x8c,
0xe5, 0xb8, 0xae, 0xe5, 0x8a, 0xa9, 0xe6, 0x96, 0x87, 0xe5, 0x8c, 0x96, 0xe8,
0xb5, 0x84, 0xe6, 0xba, 0x90, 0xe5, 0xa4, 0xa7, 0xe5, 0xad, 0xa6, 0xe5, 0xad,
0xa6, 0xe4, 0xb9, 0xa0, 0xe5, 0x9c, 0xb0, 0xe5, 0x9d, 0x80, 0xe6, 0xb5, 0x8f,
0xe8, 0xa7, 0x88, 0xe6, 0x8a, 0x95, 0xe8, 0xb5, 0x84, 0xe5, 0xb7, 0xa5, 0xe7,
0xa8, 0x8b, 0xe8, 0xa6, 0x81, 0xe6, 0xb1, 0x82, 0xe6, 0x80, 0x8e, 0xe4, 0xb9,
0x88, 0xe6, 0x97, 0xb6, 0xe5, 0x80, 0x99, 0xe5, 0x8a, 0x9f, 0xe8, 0x83, 0xbd,
0xe4, 0xb8, 0xbb, 0xe8, 0xa6, 0x81, 0xe7, 0x9b, 0xae, 0xe5, 0x89, 0x8d, 0xe8,
0xb5, 0x84, 0xe8, 0xae, 0xaf, 0xe5, 0x9f, 0x8e, 0xe
gitextract_ur_7czr5/ ├── .editorconfig ├── .gitattributes ├── .github/ │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE │ ├── PULL_REQUEST_TEMPLATE │ └── workflows/ │ └── test.yml ├── .gitignore ├── .vscode/ │ ├── extensions.json │ └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bin/ │ └── ttf2woff2.js ├── binding.gyp ├── csrc/ │ ├── addon.cc │ ├── enc/ │ │ ├── backward_references.cc │ │ ├── backward_references.h │ │ ├── bit_cost.h │ │ ├── block_splitter.cc │ │ ├── block_splitter.h │ │ ├── brotli_bit_stream.cc │ │ ├── brotli_bit_stream.h │ │ ├── cluster.h │ │ ├── command.h │ │ ├── context.h │ │ ├── dictionary.h │ │ ├── dictionary_hash.h │ │ ├── encode.cc │ │ ├── encode.h │ │ ├── encode_parallel.cc │ │ ├── encode_parallel.h │ │ ├── entropy_encode.cc │ │ ├── entropy_encode.h │ │ ├── fast_log.h │ │ ├── find_match_length.h │ │ ├── hash.h │ │ ├── histogram.cc │ │ ├── histogram.h │ │ ├── literal_cost.cc │ │ ├── literal_cost.h │ │ ├── metablock.cc │ │ ├── metablock.h │ │ ├── port.h │ │ ├── prefix.h │ │ ├── ringbuffer.h │ │ ├── static_dict.h │ │ ├── streams.cc │ │ ├── streams.h │ │ ├── streams.h.gch │ │ ├── transform.h │ │ └── write_bits.h │ ├── fallback.cc │ └── woff2/ │ ├── buffer.h │ ├── font.cc │ ├── font.h │ ├── glyph.cc │ ├── glyph.h │ ├── normalize.cc │ ├── normalize.h │ ├── port.h │ ├── round.h │ ├── store_bytes.h │ ├── table_tags.cc │ ├── table_tags.h │ ├── transform.cc │ ├── transform.h │ ├── variable_length.cc │ ├── variable_length.h │ ├── woff2_common.cc │ ├── woff2_common.h │ ├── woff2_dec.cc │ ├── woff2_dec.h │ ├── woff2_enc.cc │ └── woff2_enc.h ├── eslint.config.js ├── install/ │ └── try-build.js ├── jssrc/ │ ├── index.js │ ├── post.js │ ├── ttf2woff2.cjs │ └── ttf2woff2.wasm ├── package.json ├── src/ │ ├── cli.test.ts │ ├── index.ts │ └── tests.test.ts └── tsconfig.json
SYMBOL INDEX (310 symbols across 61 files)
FILE: csrc/addon.cc
function NAN_METHOD (line 9) | NAN_METHOD(convert) {
function NAN_MODULE_INIT (line 51) | NAN_MODULE_INIT(Init) {
FILE: csrc/enc/backward_references.cc
type brotli (line 24) | namespace brotli {
function CreateBackwardReferences (line 27) | void CreateBackwardReferences(size_t num_bytes,
function CreateBackwardReferences (line 290) | void CreateBackwardReferences(size_t num_bytes,
FILE: csrc/enc/backward_references.h
function namespace (line 26) | namespace brotli {
FILE: csrc/enc/bit_cost.h
function namespace (line 25) | namespace brotli {
FILE: csrc/enc/block_splitter.cc
type brotli (line 32) | namespace brotli {
function CopyLiteralsToByteArray (line 48) | void CopyLiteralsToByteArray(const Command* cmds,
function CopyCommandsToByteArray (line 74) | void CopyCommandsToByteArray(const Command* cmds,
function MyRand (line 87) | inline static unsigned int MyRand(unsigned int* seed) {
function InitialEntropyCodes (line 96) | void InitialEntropyCodes(const DataType* data, size_t length,
function RandomSample (line 122) | void RandomSample(unsigned int* seed,
function RefineEntropyCodes (line 138) | void RefineEntropyCodes(const DataType* data, size_t length,
function BitCost (line 153) | inline static float BitCost(int total, int count) {
function FindBlocks (line 158) | void FindBlocks(const DataType* data, const size_t length,
function RemapBlockIds (line 229) | int RemapBlockIds(uint8_t* block_ids, const size_t length) {
function BuildBlockHistograms (line 245) | void BuildBlockHistograms(const DataType* data, const size_t length,
function ClusterBlocks (line 257) | void ClusterBlocks(const DataType* data, const size_t length,
function BuildBlockSplit (line 286) | void BuildBlockSplit(const std::vector<uint8_t>& block_ids, BlockSplit...
function SplitByteVector (line 307) | void SplitByteVector(const std::vector<DataType>& data,
function SplitBlock (line 345) | void SplitBlock(const Command* cmds,
function SplitBlockByTotalLength (line 379) | void SplitBlockByTotalLength(const Command* all_commands,
FILE: csrc/enc/block_splitter.h
function namespace (line 29) | namespace brotli {
function Next (line 39) | void Next() {
FILE: csrc/enc/brotli_bit_stream.cc
type brotli (line 32) | namespace brotli {
function EncodeMlen (line 36) | bool EncodeMlen(size_t length, int* bits, int* numbits, int* nibblesbi...
function StoreVarLenUint8 (line 47) | void StoreVarLenUint8(int n, int* storage_ix, uint8_t* storage) {
function StoreCompressedMetaBlockHeader (line 58) | bool StoreCompressedMetaBlockHeader(bool final_block,
function StoreUncompressedMetaBlockHeader (line 94) | bool StoreUncompressedMetaBlockHeader(size_t length,
function StoreHuffmanTreeOfHuffmanTreeToBitMask (line 112) | void StoreHuffmanTreeOfHuffmanTreeToBitMask(
function StoreHuffmanTreeToBitMask (line 162) | void StoreHuffmanTreeToBitMask(
function StoreSimpleHuffmanTree (line 185) | void StoreSimpleHuffmanTree(const uint8_t* depths,
function StoreHuffmanTree (line 222) | void StoreHuffmanTree(const uint8_t* depths, size_t num,
function BuildAndStoreHuffmanTree (line 278) | void BuildAndStoreHuffmanTree(const int *histogram,
function IndexOf (line 320) | int IndexOf(const std::vector<int>& v, int value) {
function MoveToFront (line 327) | void MoveToFront(std::vector<int>* v, int index) {
function MoveToFrontTransform (line 335) | std::vector<int> MoveToFrontTransform(const std::vector<int>& v) {
function RunLengthCodeZeros (line 354) | void RunLengthCodeZeros(const std::vector<int>& v_in,
function BestMaxZeroRunLengthPrefix (line 399) | int BestMaxZeroRunLengthPrefix(const std::vector<int>& v) {
function EncodeContextMap (line 427) | void EncodeContextMap(const std::vector<int>& context_map,
function StoreBlockSwitch (line 469) | void StoreBlockSwitch(const BlockSplitCode& code,
function BuildAndStoreBlockSplitCode (line 485) | void BuildAndStoreBlockSplitCode(const std::vector<int>& types,
function StoreTrivialContextMap (line 531) | void StoreTrivialContextMap(int num_types,
class BlockEncoder (line 566) | class BlockEncoder {
method BlockEncoder (line 568) | BlockEncoder(int alphabet_size,
method BuildAndStoreBlockSwitchEntropyCodes (line 582) | void BuildAndStoreBlockSwitchEntropyCodes(int* storage_ix, uint8_t* ...
method BuildAndStoreEntropyCodes (line 591) | void BuildAndStoreEntropyCodes(
method StoreSymbol (line 606) | void StoreSymbol(int symbol, int* storage_ix, uint8_t* storage) {
method StoreSymbolWithContext (line 622) | void StoreSymbolWithContext(int symbol, int context,
function JumpToByteBoundary (line 650) | void JumpToByteBoundary(int* storage_ix, uint8_t* storage) {
function StoreMetaBlock (line 655) | bool StoreMetaBlock(const uint8_t* input,
function StoreUncompressedMetaBlock (line 783) | bool StoreUncompressedMetaBlock(bool final_block,
function StoreSyncMetaBlock (line 819) | void StoreSyncMetaBlock(int * __restrict storage_ix,
FILE: csrc/enc/brotli_bit_stream.h
function namespace (line 33) | namespace brotli {
FILE: csrc/enc/cluster.h
function namespace (line 35) | namespace brotli {
function ClusterCostDiff (line 55) | inline double ClusterCostDiff(int size_a, int size_b) {
FILE: csrc/enc/command.h
function namespace (line 23) | namespace brotli {
function DistanceContext (line 131) | int DistanceContext() const {
FILE: csrc/enc/context.h
function namespace (line 22) | namespace brotli {
FILE: csrc/enc/dictionary_hash.h
function namespace (line 22) | namespace brotli {
FILE: csrc/enc/encode.cc
type brotli (line 38) | namespace brotli {
function ParseAsUTF8 (line 42) | int ParseAsUTF8(int* symbol, const uint8_t* input, int size) {
function IsMostlyUTF8 (line 92) | bool IsMostlyUTF8(const uint8_t* data, size_t length, double min_fract...
function RecomputeDistancePrefixes (line 104) | void RecomputeDistancePrefixes(Command* cmds,
function BrotliCompressBuffer (line 516) | int BrotliCompressBuffer(BrotliParams params,
function CopyOneBlockToRingBuffer (line 535) | size_t CopyOneBlockToRingBuffer(BrotliIn* r, BrotliCompressor* compres...
function BrotliInIsFinished (line 562) | bool BrotliInIsFinished(BrotliIn* r) {
function BrotliCompress (line 567) | int BrotliCompress(BrotliParams params, BrotliIn* in, BrotliOut* out) {
FILE: csrc/enc/encode.h
function namespace (line 30) | namespace brotli {
FILE: csrc/enc/encode_parallel.cc
type brotli (line 38) | namespace brotli {
function ParseAsUTF8 (line 42) | int ParseAsUTF8(int* symbol, const uint8_t* input, int size) {
function IsMostlyUTF8 (line 92) | bool IsMostlyUTF8(const uint8_t* data, size_t length, double min_fract...
function RecomputeDistancePrefixes (line 103) | void RecomputeDistancePrefixes(std::vector<Command>* cmds,
function WriteMetaBlockParallel (line 122) | bool WriteMetaBlockParallel(const BrotliParams& params,
function BrotliCompressBufferParallel (line 283) | int BrotliCompressBufferParallel(BrotliParams params,
FILE: csrc/enc/encode_parallel.h
function namespace (line 27) | namespace brotli {
FILE: csrc/enc/entropy_encode.cc
type brotli (line 27) | namespace brotli {
type HuffmanTree (line 31) | struct HuffmanTree {
method HuffmanTree (line 33) | HuffmanTree(int count, int16_t left, int16_t right)
function SortHuffmanTree (line 46) | bool SortHuffmanTree(const HuffmanTree &v0, const HuffmanTree &v1) {
function SetDepth (line 50) | void SetDepth(const HuffmanTree &p,
function CreateHuffmanTree (line 80) | void CreateHuffmanTree(const int *data,
function Reverse (line 158) | void Reverse(std::vector<uint8_t>* v, int start, int end) {
function WriteHuffmanTreeRepetitions (line 169) | void WriteHuffmanTreeRepetitions(
function WriteHuffmanTreeRepetitionsZeros (line 204) | void WriteHuffmanTreeRepetitionsZeros(
function OptimizeHuffmanCountsForRle (line 232) | int OptimizeHuffmanCountsForRle(int length, int* counts) {
function DecideOverRleUse (line 370) | static void DecideOverRleUse(const uint8_t* depth, const int length,
function WriteHuffmanTree (line 399) | void WriteHuffmanTree(const uint8_t* depth,
function ReverseBits (line 448) | uint16_t ReverseBits(int num_bits, uint16_t bits) {
function ConvertBitDepthsToSymbols (line 465) | void ConvertBitDepthsToSymbols(const uint8_t *depth, int len, uint16_t...
FILE: csrc/enc/entropy_encode.h
function namespace (line 26) | namespace brotli {
FILE: csrc/enc/fast_log.h
function namespace (line 24) | namespace brotli {
FILE: csrc/enc/find_match_length.h
function namespace (line 26) | namespace brotli {
FILE: csrc/enc/hash.h
function namespace (line 38) | namespace brotli {
function SetStaticDictionary (line 617) | void SetStaticDictionary(const StaticDictionary *dict) {
FILE: csrc/enc/histogram.cc
type brotli (line 27) | namespace brotli {
function BuildHistograms (line 29) | void BuildHistograms(
FILE: csrc/enc/histogram.h
function namespace (line 28) | namespace brotli {
type Histogram (line 76) | typedef Histogram<256> HistogramLiteral;
type Histogram (line 78) | typedef Histogram<kNumCommandPrefixes> HistogramCommand;
type Histogram (line 79) | typedef Histogram<kNumDistancePrefixes> HistogramDistance;
type Histogram (line 80) | typedef Histogram<kNumBlockLenPrefixes> HistogramBlockLength;
type Histogram (line 82) | typedef Histogram<272> HistogramContextMap;
type Histogram (line 84) | typedef Histogram<258> HistogramBlockType;
FILE: csrc/enc/literal_cost.cc
type brotli (line 25) | namespace brotli {
function UTF8Position (line 27) | static int UTF8Position(int last, int c, int clamp) {
function DecideMultiByteStatsLevel (line 42) | static int DecideMultiByteStatsLevel(size_t pos, size_t len, size_t mask,
function EstimateBitCostsForLiteralsUTF8 (line 63) | void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask,
function EstimateBitCostsForLiterals (line 133) | void EstimateBitCostsForLiterals(size_t pos, size_t len, size_t mask,
FILE: csrc/enc/literal_cost.h
function namespace (line 23) | namespace brotli {
FILE: csrc/enc/metablock.cc
type brotli (line 24) | namespace brotli {
function BuildMetaBlock (line 26) | void BuildMetaBlock(const uint8_t* ringbuffer,
class BlockSplitter (line 106) | class BlockSplitter {
method BlockSplitter (line 108) | BlockSplitter(int alphabet_size,
method AddSymbol (line 136) | void AddSymbol(int symbol) {
method FinishBlock (line 148) | void FinishBlock(bool is_final) {
function BuildMetaBlockGreedy (line 261) | void BuildMetaBlockGreedy(const uint8_t* ringbuffer,
function OptimizeHistograms (line 300) | void OptimizeHistograms(int num_direct_distance_codes,
FILE: csrc/enc/metablock.h
type MetaBlockSplit (line 36) | struct MetaBlockSplit {
FILE: csrc/enc/port.h
function BROTLI_UNALIGNED_LOAD64 (line 106) | inline uint64_t BROTLI_UNALIGNED_LOAD64(const void *p) {
function BROTLI_UNALIGNED_STORE64 (line 112) | inline void BROTLI_UNALIGNED_STORE64(void *p, uint64_t v) {
function BROTLI_UNALIGNED_LOAD32 (line 121) | inline uint32_t BROTLI_UNALIGNED_LOAD32(const void *p) {
function BROTLI_UNALIGNED_LOAD64 (line 127) | inline uint64_t BROTLI_UNALIGNED_LOAD64(const void *p) {
function BROTLI_UNALIGNED_STORE32 (line 133) | inline void BROTLI_UNALIGNED_STORE32(void *p, uint32_t v) {
function BROTLI_UNALIGNED_STORE64 (line 137) | inline void BROTLI_UNALIGNED_STORE64(void *p, uint64_t v) {
FILE: csrc/enc/prefix.h
function namespace (line 24) | namespace brotli {
FILE: csrc/enc/ringbuffer.h
function namespace (line 25) | namespace brotli {
FILE: csrc/enc/static_dict.h
function namespace (line 27) | namespace brotli {
FILE: csrc/enc/streams.cc
type brotli (line 23) | namespace brotli {
FILE: csrc/enc/streams.h
function namespace (line 25) | namespace brotli {
FILE: csrc/enc/transform.h
function namespace (line 24) | namespace brotli {
FILE: csrc/enc/write_bits.h
function namespace (line 26) | namespace brotli {
FILE: csrc/fallback.cc
function getSizePtr (line 9) | int getSizePtr() {
function convert (line 14) | int convert(int inputDataAddress, int inputLength, int outputSizePtrAddr...
function freePtrs (line 43) | void freePtrs(int outputDataAddress, int sizePtrAddress) {
function EMSCRIPTEN_BINDINGS (line 50) | EMSCRIPTEN_BINDINGS(ttf2woff2_fallback) {
FILE: csrc/woff2/buffer.h
type __int64 (line 29) | typedef __int64 int64_t;
function namespace (line 45) | namespace woff2 {
FILE: csrc/woff2/font.cc
type woff2 (line 27) | namespace woff2 {
function ReadTrueTypeFont (line 70) | bool ReadTrueTypeFont(Buffer* file, const uint8_t* data, size_t len,
function ReadCollectionFont (line 114) | bool ReadCollectionFont(Buffer* file, const uint8_t* data, size_t len,
function ReadTrueTypeCollection (line 137) | bool ReadTrueTypeCollection(Buffer* file, const uint8_t* data, size_t ...
function ReadFont (line 170) | bool ReadFont(const uint8_t* data, size_t len, Font* font) {
function ReadFontCollection (line 183) | bool ReadFontCollection(const uint8_t* data, size_t len,
function FontFileSize (line 201) | size_t FontFileSize(const Font& font) {
function FontCollectionFileSize (line 212) | size_t FontCollectionFileSize(const FontCollection& font_collection) {
function WriteFont (line 221) | bool WriteFont(const Font& font, uint8_t* dst, size_t dst_size) {
function WriteTableRecord (line 226) | bool WriteTableRecord(const Font::Table* table, size_t* offset, uint8_...
function WriteTable (line 241) | bool WriteTable(const Font::Table& table, size_t* offset, uint8_t* dst,
function WriteFont (line 264) | bool WriteFont(const Font& font, size_t* offset, uint8_t* dst,
function WriteFontCollection (line 287) | bool WriteFontCollection(const FontCollection& font_collection, uint8_...
function NumGlyphs (line 325) | int NumGlyphs(const Font& font) {
function IndexFormat (line 336) | int IndexFormat(const Font& font) {
function GetGlyphData (line 348) | bool GetGlyphData(const Font& font, int glyph_index,
function RemoveDigitalSignature (line 390) | bool RemoveDigitalSignature(Font* font) {
FILE: csrc/woff2/font.h
function namespace (line 26) | namespace woff2 {
FILE: csrc/woff2/glyph.cc
type woff2 (line 24) | namespace woff2 {
function ReadCompositeGlyphData (line 39) | bool ReadCompositeGlyphData(Buffer* buffer, Glyph* glyph) {
function ReadGlyph (line 73) | bool ReadGlyph(const uint8_t* data, size_t len, Glyph* glyph) {
function StoreBbox (line 221) | void StoreBbox(const Glyph& glyph, size_t* offset, uint8_t* dst) {
function StoreInstructions (line 228) | void StoreInstructions(const Glyph& glyph, size_t* offset, uint8_t* ds...
function StoreEndPtsOfContours (line 233) | bool StoreEndPtsOfContours(const Glyph& glyph, size_t* offset, uint8_t...
function StorePoints (line 246) | bool StorePoints(const Glyph& glyph, size_t* offset,
function StoreGlyph (line 342) | bool StoreGlyph(const Glyph& glyph, uint8_t* dst, size_t* dst_size) {
FILE: csrc/woff2/glyph.h
function namespace (line 25) | namespace woff2 {
FILE: csrc/woff2/normalize.cc
type woff2 (line 31) | namespace woff2 {
function StoreLoca (line 35) | void StoreLoca(int index_fmt, uint32_t value, size_t* offset, uint8_t*...
function WriteNormalizedLoca (line 47) | bool WriteNormalizedLoca(int index_fmt, int num_glyphs, Font* font) {
function MakeEditableBuffer (line 99) | bool MakeEditableBuffer(Font* font, int tableTag) {
function NormalizeGlyphs (line 117) | bool NormalizeGlyphs(Font* font) {
function NormalizeOffsets (line 175) | bool NormalizeOffsets(Font* font) {
function ComputeHeaderChecksum (line 187) | uint32_t ComputeHeaderChecksum(const Font& font) {
function FixChecksums (line 209) | bool FixChecksums(Font* font) {
function MarkTransformed (line 247) | bool MarkTransformed(Font* font) {
function NormalizeWithoutFixingChecksums (line 267) | bool NormalizeWithoutFixingChecksums(Font* font) {
function NormalizeFont (line 275) | bool NormalizeFont(Font* font) {
function NormalizeFontCollection (line 280) | bool NormalizeFontCollection(FontCollection* font_collection) {
FILE: csrc/woff2/normalize.h
function namespace (line 22) | namespace woff2 {
FILE: csrc/woff2/port.h
function namespace (line 22) | namespace woff2 {
FILE: csrc/woff2/round.h
function namespace (line 22) | namespace woff2 {
FILE: csrc/woff2/store_bytes.h
function namespace (line 25) | namespace woff2 {
FILE: csrc/woff2/table_tags.cc
type woff2 (line 19) | namespace woff2 {
FILE: csrc/woff2/table_tags.h
function namespace (line 22) | namespace woff2 {
FILE: csrc/woff2/transform.cc
type woff2 (line 27) | namespace woff2 {
function WriteBytes (line 34) | void WriteBytes(std::vector<uint8_t>* out, const uint8_t* data, size_t...
function WriteBytes (line 41) | void WriteBytes(std::vector<uint8_t>* out, const std::vector<uint8_t>&...
function WriteUShort (line 47) | void WriteUShort(std::vector<uint8_t>* out, int value) {
function WriteLong (line 52) | void WriteLong(std::vector<uint8_t>* out, int value) {
class GlyfEncoder (line 61) | class GlyfEncoder {
method GlyfEncoder (line 63) | explicit GlyfEncoder(int num_glyphs)
method Encode (line 68) | bool Encode(int glyph_id, const Glyph& glyph) {
method GetTransformedGlyfBytes (line 79) | void GetTransformedGlyfBytes(std::vector<uint8_t>* result) {
method WriteInstructions (line 101) | void WriteInstructions(const Glyph& glyph) {
method ShouldWriteSimpleGlyphBbox (line 107) | bool ShouldWriteSimpleGlyphBbox(const Glyph& glyph) {
method WriteSimpleGlyph (line 137) | void WriteSimpleGlyph(int glyph_id, const Glyph& glyph) {
method WriteCompositeGlyph (line 165) | void WriteCompositeGlyph(int glyph_id, const Glyph& glyph) {
method WriteBbox (line 176) | void WriteBbox(int glyph_id, const Glyph& glyph) {
method WriteTriplet (line 184) | void WriteTriplet(bool on_curve, int x, int y) {
function TransformGlyfAndLocaTables (line 238) | bool TransformGlyfAndLocaTables(Font* font) {
FILE: csrc/woff2/transform.h
function namespace (line 22) | namespace woff2 {
FILE: csrc/woff2/variable_length.cc
type woff2 (line 19) | namespace woff2 {
function Size255UShort (line 21) | size_t Size255UShort(uint16_t value) {
function Write255UShort (line 33) | void Write255UShort(std::vector<uint8_t>* out, int value) {
function Store255UShort (line 49) | void Store255UShort(int val, size_t* offset, uint8_t* dst) {
function Read255UShort (line 58) | bool Read255UShort(Buffer* buf, unsigned int* value) {
function ReadBase128 (line 94) | bool ReadBase128(Buffer* buf, uint32_t* value) {
function Base128Size (line 115) | size_t Base128Size(size_t n) {
function StoreBase128 (line 121) | void StoreBase128(size_t len, size_t* offset, uint8_t* dst) {
FILE: csrc/woff2/variable_length.h
function namespace (line 24) | namespace woff2 {
FILE: csrc/woff2/woff2_common.cc
type woff2 (line 21) | namespace woff2 {
function ComputeULongSum (line 24) | uint32_t ComputeULongSum(const uint8_t* buf, size_t size) {
function CollectionHeaderSize (line 34) | size_t CollectionHeaderSize(uint32_t header_version, uint32_t num_font...
FILE: csrc/woff2/woff2_common.h
function namespace (line 25) | namespace woff2 {
FILE: csrc/woff2/woff2_dec.cc
type woff2 (line 36) | namespace woff2 {
type TtcFont (line 67) | struct TtcFont {
function WithSign (line 73) | int WithSign(int flag, int baseval) {
function TripletDecode (line 78) | bool TripletDecode(const uint8_t* flags_in, const uint8_t* in, size_t ...
function StorePoints (line 149) | bool StorePoints(const std::vector<Point>& points,
function ComputeBbox (line 250) | void ComputeBbox(const std::vector<Point>& points, uint8_t* dst) {
function ProcessBboxStream (line 273) | bool ProcessBboxStream(Buffer* bbox_stream, unsigned int n_glyphs,
function ProcessComposite (line 303) | bool ProcessComposite(Buffer* composite_stream, uint8_t* dst,
function StoreLoca (line 345) | bool StoreLoca(const std::vector<uint32_t>& loca_values, int index_for...
function ReconstructGlyf (line 368) | bool ReconstructGlyf(const uint8_t* data, size_t data_size,
function Table (line 538) | const Table* FindTable(const std::vector<Table>& tables, uint32_t tag) {
function ReconstructTransformedGlyf (line 548) | bool ReconstructTransformedGlyf(const uint8_t* transformed_buf,
function ReconstructTransformed (line 567) | bool ReconstructTransformed(const std::vector<Table>& tables, uint32_t...
function ComputeChecksum (line 587) | uint32_t ComputeChecksum(const Table* table, const uint8_t* dst) {
function Table (line 591) | const Table* FindTable(TtcFont ttc_font, const std::vector<Table>& tab...
function FixCollectionChecksums (line 599) | bool FixCollectionChecksums(size_t header_version,
function FixChecksums (line 653) | bool FixChecksums(const std::vector<Table>& tables, uint8_t* dst) {
function Woff2Uncompress (line 675) | bool Woff2Uncompress(uint8_t* dst_buf, size_t dst_size,
function ReadTableDirectory (line 686) | bool ReadTableDirectory(Buffer* file, std::vector<Table>* tables,
function ComputeWOFF2FinalSize (line 737) | size_t ComputeWOFF2FinalSize(const uint8_t* data, size_t length) {
function StoreOffsetTable (line 749) | size_t StoreOffsetTable(uint8_t* result, size_t offset, uint32_t flavor,
function StoreTableEntry (line 765) | size_t StoreTableEntry(uint8_t* result, const Table& table, size_t off...
function ComputeOffsetToFirstTable (line 774) | uint64_t ComputeOffsetToFirstTable(const uint32_t header_version,
function ConvertWOFF2ToTTF (line 790) | bool ConvertWOFF2ToTTF(uint8_t* result, size_t result_length,
FILE: csrc/woff2/woff2_dec.h
function namespace (line 23) | namespace woff2 {
FILE: csrc/woff2/woff2_enc.cc
type woff2 (line 37) | namespace woff2 {
function Compress (line 48) | bool Compress(const uint8_t* data, const size_t len,
function Woff2Compress (line 62) | bool Woff2Compress(const uint8_t* data, const size_t len,
function TextCompress (line 68) | bool TextCompress(const uint8_t* data, const size_t len,
function KnownTableIndex (line 74) | int KnownTableIndex(uint32_t tag) {
function StoreTableEntry (line 81) | void StoreTableEntry(const Table& table, size_t* offset, uint8_t* dst) {
function TableEntrySize (line 96) | size_t TableEntrySize(const Table& table) {
function ComputeWoff2Length (line 106) | size_t ComputeWoff2Length(const FontCollection& font_collection,
function ComputeTTFLength (line 146) | size_t ComputeTTFLength(const std::vector<Table>& tables) {
function ComputeUncompressedLength (line 154) | size_t ComputeUncompressedLength(const Font& font) {
function ComputeUncompressedLength (line 166) | size_t ComputeUncompressedLength(const FontCollection& font_collection) {
function ComputeTotalTransformLength (line 178) | size_t ComputeTotalTransformLength(const Font& font) {
function MaxWOFF2CompressedSize (line 196) | size_t MaxWOFF2CompressedSize(const uint8_t* data, size_t length) {
function MaxWOFF2CompressedSize (line 200) | size_t MaxWOFF2CompressedSize(const uint8_t* data, size_t length,
function CompressedBufferSize (line 209) | uint32_t CompressedBufferSize(uint32_t original_size) {
function ConvertTTFToWOFF2 (line 213) | bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
function TransformFontCollection (line 218) | bool TransformFontCollection(FontCollection* font_collection) {
function ConvertTTFToWOFF2 (line 229) | bool ConvertTTFToWOFF2(const uint8_t *data, size_t length,
FILE: csrc/woff2/woff2_enc.h
function namespace (line 27) | namespace woff2 {
FILE: jssrc/index.js
function ttf2woff2 (line 4) | function ttf2woff2(inputContent) {
FILE: jssrc/ttf2woff2.cjs
function locateFile (line 1) | function locateFile(path){if(Module["locateFile"]){return Module["locate...
function updateMemoryViews (line 1) | function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEA...
function preRun (line 1) | function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="func...
function initRuntime (line 1) | function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__AT...
function postRun (line 1) | function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="f...
function addOnPreRun (line 1) | function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}
function addOnInit (line 1) | function addOnInit(cb){__ATINIT__.unshift(cb)}
function addOnPostRun (line 1) | function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}
function addRunDependency (line 1) | function addRunDependency(id){runDependencies++;Module["monitorRunDepend...
function removeRunDependency (line 1) | function removeRunDependency(id){runDependencies--;Module["monitorRunDep...
function abort (line 1) | function abort(what){Module["onAbort"]?.(what);what="Aborted("+what+")";...
function findWasmBinary (line 1) | function findWasmBinary(){var f="ttf2woff2.wasm";if(!isDataURI(f)){retur...
function getBinarySync (line 1) | function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return...
function instantiateSync (line 1) | function instantiateSync(file,info){var module;var binary=getBinarySync(...
function getWasmImports (line 1) | function getWasmImports(){return{env:wasmImports,wasi_snapshot_preview1:...
function createWasm (line 1) | function createWasm(){var info=getWasmImports();function receiveInstance...
function getValue (line 1) | function getValue(ptr,type="i8"){if(type.endsWith("*"))type="*";switch(t...
class ExceptionInfo (line 1) | class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excP...
method constructor (line 1) | constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}
method set_type (line 1) | set_type(type){HEAPU32[this.ptr+4>>2]=type}
method get_type (line 1) | get_type(){return HEAPU32[this.ptr+4>>2]}
method set_destructor (line 1) | set_destructor(destructor){HEAPU32[this.ptr+8>>2]=destructor}
method get_destructor (line 1) | get_destructor(){return HEAPU32[this.ptr+8>>2]}
method set_caught (line 1) | set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12]=caught}
method get_caught (line 1) | get_caught(){return HEAP8[this.ptr+12]!=0}
method set_rethrown (line 1) | set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13]=rethrown}
method get_rethrown (line 1) | get_rethrown(){return HEAP8[this.ptr+13]!=0}
method init (line 1) | init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);thi...
method set_adjusted_ptr (line 1) | set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>2]=adjustedPtr}
method get_adjusted_ptr (line 1) | get_adjusted_ptr(){return HEAPU32[this.ptr+16>>2]}
method get_exception_ptr (line 1) | get_exception_ptr(){var isPointer=___cxa_is_pointer_type(this.get_type...
function onComplete (line 1) | function onComplete(typeConverters){var myTypeConverters=getTypeConverte...
function sharedRegisterType (line 1) | function sharedRegisterType(rawType,registeredInstance,options={}){var n...
function registerType (line 1) | function registerType(rawType,registeredInstance,options={}){if(!("argPa...
function readPointer (line 1) | function readPointer(pointer){return this["fromWireType"](HEAPU32[pointe...
function usesDestructorStack (line 1) | function usesDestructorStack(argTypes){for(var i=1;i<argTypes.length;++i...
function newFunc (line 1) | function newFunc(constructor,argumentList){if(!(constructor instanceof F...
function createJsInvoker (line 1) | function createJsInvoker(argTypes,isClassMethodFunc,returns,isAsync){var...
function craftInvokerFunction (line 1) | function craftInvokerFunction(humanName,argTypes,classType,cppInvokerFun...
function makeDynCaller (line 1) | function makeDynCaller(){if(signature.includes("j")){return getDynCaller...
function visit (line 1) | function visit(type){if(seen[type]){return}if(registeredTypes[type]){ret...
function decodeMemoryView (line 1) | function decodeMemoryView(handle){var size=HEAPU32[handle>>2];var data=H...
method fromWireType (line 1) | fromWireType(value){var length=HEAPU32[value>>2];var payload=value+4;var...
method toWireType (line 1) | toWireType(destructors,value){if(value instanceof ArrayBuffer){value=new...
method destructorFunction (line 1) | destructorFunction(ptr){_free(ptr)}
method destructorFunction (line 1) | destructorFunction(ptr){_free(ptr)}
function _fd_seek (line 1) | function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset...
method constructor (line 1) | constructor(message){super(message);this.name="BindingError"}
method constructor (line 1) | constructor(message){super(message);this.name="InternalError"}
function run (line 1) | function run(){if(runDependencies>0){return}preRun();if(runDependencies>...
FILE: src/index.ts
function getExecutable (line 10) | function getExecutable() {
Condensed preview — 87 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,489K chars).
[
{
"path": ".editorconfig",
"chars": 520,
"preview": "# This file is automatically generated by a `metapak`\n# module. Do not change it elsewhere, changes would\n# be overridde"
},
{
"path": ".gitattributes",
"chars": 43,
"preview": "# Enforce Unix newlines\n* text=auto eol=lf\n"
},
{
"path": ".github/CODE_OF_CONDUCT.md",
"chars": 277,
"preview": "# Code of Conduct\n\nBe kind, except if I behave like an asshole, if so, tell me by linking to this\n file.\n\nI try hard to "
},
{
"path": ".github/CONTRIBUTING",
"chars": 258,
"preview": "Contributing to this project requires you to be\n a gentleman.\n\nBy contributing you must agree with publishing your\n chan"
},
{
"path": ".github/FUNDING.yml",
"chars": 20,
"preview": "github: [nfroidure]\n"
},
{
"path": ".github/ISSUE_TEMPLATE",
"chars": 1380,
"preview": "## Issue\n<!--\n\nThanks for reporting an issue.\n\nBefore doing so, there are a few checks to do in\n order to optimize its r"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE",
"chars": 1334,
"preview": "<!--\n\nThanks for improving this project!\n\nBefore doing so, there are a few checks to do in\n order to get your PR merged "
},
{
"path": ".github/workflows/test.yml",
"chars": 418,
"preview": "on: [push, pull_request]\nname: Run tests\njobs:\n test:\n strategy:\n matrix:\n node: [20, 22, 23]\n os"
},
{
"path": ".gitignore",
"chars": 2146,
"preview": "# This file is automatically generated by a `metapak`\n# module. Do not change it elsewhere, changes would\n# be overridde"
},
{
"path": ".vscode/extensions.json",
"chars": 118,
"preview": "{\n \"recommendations\": [\n \"dbaeumer.vscode-eslint\",\n \"esbenp.prettier-vscode\",\n \"gruntfuggly.todo-tree\"\n ]\n}"
},
{
"path": ".vscode/settings.json",
"chars": 55,
"preview": "{\n \"typescript.tsdk\": \"node_modules/typescript/lib\"\n}\n"
},
{
"path": "CHANGELOG.md",
"chars": 4122,
"preview": "## [8.0.1](https://github.com/nfroidure/ttf2woff2/compare/v8.0.0...v8.0.1) (2026-02-28)\n\n\n### Bug Fixes\n\n* **build:** in"
},
{
"path": "LICENSE",
"chars": 1080,
"preview": "The MIT License (MIT)\nCopyright © 2017 Nicolas Froidure\n\nPermission is hereby granted, free of charge, to any person obt"
},
{
"path": "README.md",
"chars": 1932,
"preview": "[//]: # ( )\n[//]: # (This file is automatically generated by a `metapak`)\n[//]: # (module. Do not change it except betw"
},
{
"path": "bin/ttf2woff2.js",
"chars": 296,
"preview": "#! /usr/bin/env node\n\nimport {\n BufferStream\n} from 'bufferstreams';\nimport ttf2woff2 from '../dist/index.js';\n\nprocess"
},
{
"path": "binding.gyp",
"chars": 1154,
"preview": "{\n \"targets\": [\n {\n \"target_name\": \"addon\",\n \"sources\": [\n \"csrc/addon.cc\",\n\n \"csrc/woff2/gl"
},
{
"path": "csrc/addon.cc",
"chars": 1602,
"preview": "#include <nan.h>\n#include <node.h>\n#include <node_buffer.h>\n#include <stdlib.h>\n#include \"./woff2/woff2_enc.h\"\n\nusing na"
},
{
"path": "csrc/enc/backward_references.cc",
"chars": 15446,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/backward_references.h",
"chars": 1695,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/bit_cost.h",
"chars": 4254,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/block_splitter.cc",
"chars": 13542,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/block_splitter.h",
"chars": 2152,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/brotli_bit_stream.cc",
"chars": 29327,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/brotli_bit_stream.h",
"chars": 5358,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/cluster.h",
"chars": 10036,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/command.h",
"chars": 4943,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/context.h",
"chars": 7657,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/dictionary.h",
"chars": 747481,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/dictionary_hash.h",
"chars": 271247,
"preview": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/encode.cc",
"chars": 20624,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/encode.h",
"chars": 6741,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/encode_parallel.cc",
"chars": 11528,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/encode_parallel.h",
"chars": 1250,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/entropy_encode.cc",
"chars": 13832,
"preview": "// Copyright 2010 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/entropy_encode.h",
"chars": 3062,
"preview": "// Copyright 2010 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/fast_log.h",
"chars": 8184,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/find_match_length.h",
"chars": 2758,
"preview": "// Copyright 2010 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/hash.h",
"chars": 24289,
"preview": "// Copyright 2010 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/histogram.cc",
"chars": 2565,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/histogram.h",
"chars": 3009,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/literal_cost.cc",
"chars": 5652,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/literal_cost.h",
"chars": 1467,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/metablock.cc",
"chars": 12070,
"preview": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/metablock.h",
"chars": 2260,
"preview": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/port.h",
"chars": 4231,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/prefix.h",
"chars": 3080,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/ringbuffer.h",
"chars": 3578,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/static_dict.h",
"chars": 2640,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/streams.cc",
"chars": 2959,
"preview": "// Copyright 2009 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/streams.h",
"chars": 3546,
"preview": "// Copyright 2009 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/transform.h",
"chars": 9459,
"preview": "// Copyright 2010 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/enc/write_bits.h",
"chars": 2896,
"preview": "// Copyright 2010 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/fallback.cc",
"chars": 1586,
"preview": "// Emscripten wrapper\n#include <emscripten/bind.h>\n#include <stdlib.h>\n#include \"./woff2/woff2_enc.h\"\n\nusing namespace e"
},
{
"path": "csrc/woff2/buffer.h",
"chars": 4632,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/font.cc",
"chars": 12352,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/font.h",
"chars": 3903,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/glyph.cc",
"chars": 11643,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/glyph.h",
"chars": 2193,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/normalize.cc",
"chars": 9319,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/normalize.h",
"chars": 1738,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/port.h",
"chars": 1185,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/round.h",
"chars": 1024,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/store_bytes.h",
"chars": 1754,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/table_tags.cc",
"chars": 2995,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/table_tags.h",
"chars": 1094,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/transform.cc",
"chars": 9653,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/transform.h",
"chars": 1100,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/variable_length.cc",
"chars": 3479,
"preview": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/variable_length.h",
"chars": 1248,
"preview": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/woff2_common.cc",
"chars": 1438,
"preview": "// Copyright 2013 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/woff2_common.h",
"chars": 1883,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/woff2_dec.cc",
"chars": 37531,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/woff2_dec.h",
"chars": 1279,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/woff2_enc.cc",
"chars": 14853,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "csrc/woff2/woff2_enc.h",
"chars": 1683,
"preview": "// Copyright 2014 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
},
{
"path": "eslint.config.js",
"chars": 775,
"preview": "// @ts-check\n// This file is automatically generated by a `metapak`\n// module. Do not change it elsewhere, changes would"
},
{
"path": "install/try-build.js",
"chars": 329,
"preview": "import { execSync } from 'node:child_process';\nimport { writeFileSync } from 'node:fs';\n\nlet output = '';\n\ntry {\n outpu"
},
{
"path": "jssrc/index.js",
"chars": 1025,
"preview": "import { YError } from 'yerror';\nimport theTTFToWOFF2Module from './ttf2woff2.cjs';\n\nexport default function ttf2woff2(i"
},
{
"path": "jssrc/post.js",
"chars": 315,
"preview": "// This file need to be append to the build in order to work with browserify\n// Shamelessly stolen here: https://github."
},
{
"path": "jssrc/ttf2woff2.cjs",
"chars": 33427,
"preview": "var Module=typeof Module!=\"undefined\"?Module:{};var ENVIRONMENT_IS_WEB=typeof window==\"object\";var ENVIRONMENT_IS_WORKER"
},
{
"path": "package.json",
"chars": 5547,
"preview": "{\n \"metapak\": {\n \"configs\": [\n \"main\",\n \"readme\",\n \"tsesm\",\n \"jest\",\n \"eslint\"\n ],\n \""
},
{
"path": "src/cli.test.ts",
"chars": 427,
"preview": "import { describe, test, expect, jest } from '@jest/globals';\nimport { readFile } from 'node:fs/promises';\n\ndescribe('Te"
},
{
"path": "src/index.ts",
"chars": 1014,
"preview": "import { YError, printStackTrace } from 'yerror';\nimport debug from 'debug';\nimport { env } from 'node:process';\nimport "
},
{
"path": "src/tests.test.ts",
"chars": 2324,
"preview": "import { describe, test, expect, jest } from '@jest/globals';\nimport { readFile } from 'node:fs/promises';\nimport { YErr"
},
{
"path": "tsconfig.json",
"chars": 438,
"preview": "{\n \"compilerOptions\": {\n \"module\": \"Node16\",\n \"moduleResolution\": \"Node16\",\n \"target\": \"es2022\",\n \"noImplic"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the nfroidure/ttf2woff2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 87 files (1.4 MB), approximately 963.9k tokens, and a symbol index with 310 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.